I can't figure out how to test if a component method is fired or not on service data condition...
service looks like:
@Injectable()
export class SomeService {
someData() {
return true;
}
}
comp:
export class SomeComponent {
constructor(private someService: SomeService) {
if (this.someService.someData()) {
this.someMethod();
} else {
console.log('keep kalm!');
}
}
someMethod() {
console.log('some method is fired!')
}
}
test:
describe('SomeComponent', () => {
let component: SomeComponent;
let fixture: ComponentFixture<SomeComponent>;
let mockSomeService = {
someData: () => true
}
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [SomeComponent],
providers: [
{
provide: SomeService, useValue: mockSomeService
}
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SomeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('method should be called', () => {
spyOn(component, 'someMethod');
expect(component.someMethod).toHaveBeenCalled();
});
});
The component someMethod fires but test fails with:
Expected spy someMethod to have been called.
How can I fix this?
Thanks in advance!
Oke It is fixed! thanks to the answer from @Supamiu
Incase someone will need it in the future:
Move the initialization into ngOnInit, remove fixture.detectChanges(); from beforeEach and execute it in the test. So:
Comp:
constructor(private someService: SomeService) { }
ngOnInit() {
if (this.someService.someData()) {
this.someMethod();
} else {
console.log('keep kalm!');
}
}
test:
beforeEach(() => {
fixture = TestBed.createComponent(SomeComponent);
component = fixture.componentInstance;
// fixture.detectChanges(); <<< Remove this
});
it('method should be called', () => {
spyOn(component, 'someMethod');
fixture.detectChanges(); // trigger ngOnInit here
expect(component.someMethod).toHaveBeenCalled();
});
you are setting up the spy too late. By the time you mount the spy on service, it has already been constructed and someMethod
has been called. So after defining
the component call the spy
it('method should be called', () => {
var spy = spyOn(component, "someMethod").and.callThrough();
expect(component).toBeDefined();
expect(spy);
expect(component.someMethod).toHaveBeenCalled();
});
You have to create the spy before you create the component, because spies can't look in the past and since your method is only called in constructor, it hasn't been called after you created the spy.
You should move your initialization to either ngOnInit
method or a simple init()
method called in constructor, this way to can call the init
method or ngOnInit
and check that someMethod
has been called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With