I want to unit test an angular component that uses a helper class. The helper class and its functions should not be part of this test and be mocked instead. The component may look like this:
import { MyHelperClass } from "./my-helper-class";
export class MyComponent {
public doStuff() {
const helper = new MyHelperClass();
if (helper.check()) {
// code I want to test
}
}
}
I want to keep out the functionality of helper.check()
from the unit test and just assume it returns true
(or false in a second test). So I want my test to look something like this:
it("#doStuff should do something, assuming helper.check() is true, () => {
// make constructor of MyHelperClass return a Mock
// (or somehow spy on helper.check() and return true?)
expect(component.doStuff()).toBe(someValue);
});
You can set up a spy that mocks the function call and returns whatever value you want for check()
. It also lets you check if that function (e.g. the spy was actually invoked and how many times, etc.).
The tricky part is, if you don't have an instance of the class, you need to set up your spy on the prototype
of your class.
Have a look at this code (dummyVariable
is just a variable to test if the code after check()
has been executed or not):
it('doStuff should do something, assuming helper.check() is true', () => {
// test the before value
expect(component.dummyVariable).toBe(false);
// set up the spy and make it return true
const spy = spyOn(MyHelperClass.prototype, 'check').and.returnValue(true);
// call our function
component.doStuff();
// check the after value
expect(component.dummyVariable).toBe(true);
// check if our spy/mocked function was actually called
expect(spy).toHaveBeenCalledTimes(1);
});
// same thing as above but this time our spy returns false
it('doStuff should do something, assuming helper.check() is false', () => {
expect(component.dummyVariable).toBe(false);
const spy = spyOn(MyHelperClass.prototype, 'check').and.returnValue(false);
component.doStuff();
expect(component.dummyVariable).toBe(false);
expect(spy).toHaveBeenCalledTimes(1);
});
You can find a working example here.