Reputation: 123
I have a ionic project with a method in the constructor of a component that is called depending of a condition. I 'm using Jasmine and I want to spyOn that method to check if it is called.
This is the constructor of the component:
export class MyComponent {
public test: boolean;
constructor(public service: MyService) {
if(test) {
service.getX();
}
}
}
In my spec.ts I have to instantiate the component in order to spyOn the method but isn't work since the method has already been called in the constructor.
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
});
it('Test case #1', () => {
component.test = true;
spyOn(component.service, 'getX'); //The method has already been called in the constructor called in beforEach above
expect(component.service.getX).toHaveBeenCalled();
})
How can I spyOn a method called in the constructor?
Upvotes: 11
Views: 14429
Reputation: 935
to mock a service in component's constructor, you need provide the mock before TestBed.createComponent
for example
beforeEach(() => {
mockService = TestBed.get(Service);
spyOn(mockService, 'getSomeValue').and.returnValue({value});
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
})
Upvotes: 9
Reputation: 31
Running on the same problem, I've just achieved to test a method called within the constructor, firing the expectation within a setTimeout:
it('should call methodName on instance', () => {
spyOn(instance, 'methodName').and.callThrough();
setTimeout(() => {
expect(instance.methodName).toHaveBeenCalled();
});
});
Upvotes: 1
Reputation:
Thank to prototype inheritance, you do it like this :
spyOn(MyService.prototype, 'getX');
const mock = new MyComponent({getX: () => null});
expect(MyService.prototype.getX).toHaveBeenCalled();
You can also do it like this, which is clearer to read :
const serviceMock = new MyService();
spyOn(serviceMock, 'getX');
const mock = new MyComponent(serviceMock);
expect(serviceMock.getX).toHaveBeenCalled();
Be sure to create a mock of your component to trigger the constructor, because if you don't, it will only be done with the TestBed (and your spy won't be in place).
Upvotes: 4