Using spyOn with different Options
- Using spyon with callThrough would make the call to actual service
- spyOn with returnValue returns the value specified without making call to real function
- spyOn withArgs does the same but takes arguments incase there is somelogic needs to change when using along callthrough
- spyOn callFake would run anonymous function withits own logic rather than calling original function to act on logic
1 2 3 4 5 6 7 8 9 | spyOn(empService, 'authenticateEmp' ).withArgs( 'Admin' ).and.callThrough();
spyOn(empService, 'authenticateEmp' ).and.returnValue( true );
spyOn(empService, 'authenticateEmp' ).withArgs( 'Admin' ).and.returnValue( true );
spyOn(empService, 'authenticateEmp' ).and.callFake( function (name, args){
return true ;
});
|
What is difference between returnValue and callFake?
If we just want a return value when a service method is called then we can use any of and.callFake or and.returnValue. Lets take below example
component file:
1 2 3 4 5 6 7 8 9 | @Component(...)
export class DependencyComponent {
constructor( private service: RandomService){....}
.....
sampleMethod() {
return this .service.randomMethod();
}
.....
}
|
unit test case for above component:
1 2 3 4 5 6 7 8 | it( 'test callFake vs returnValue' , () => {
let randomService= new RandomService();
let component = new DependencyComponent(randomService);
spyOn(randomService, 'randomMethod' ).and.callFake(() => 4)
expect(component.sampleMethod()).toBe(4)
spyOn(randomService, 'randomMethod' ).and.returnValue(10);
expect(component.sampleMethod()).toBe(10)
})
|
in above case both the ways are correct.
Suppose we are passing a parameter to service method to perform its logic then in that case we have to use and.callFake((param) => {…}). Here param parameter will be the argument passed to the spied method.
component file:
1 2 3 4 5 6 7 8 9 | @Component(...)
export class DependencyComponent {
constructor( private service: RandomService){....}
.....
sampleMethod(val) {
return this .service.randomMethod(val);
}
.....
}
|
unit test case for above component:
1 2 3 4 5 6 7 | it( 'test callFake vs returnValue' , () => {
let randomService= new RandomService();
let component = new DependencyComponent(randomService);
spyOn(randomService, 'randomMethod' ).and.callFake((param) => param+4)
expect(component.sampleMethod(4)).toBe(8);
expect(component.sampleMethod(12)).toBe(16)
})
|
when component.sampleMethod(4) is executed it will call this.service.randomMethod(4). As randomMethod() is being spied using and.callFake therefore 4 will be passed as argument of call back function of and.callFake.
One obvious question is can i use returnValue instead of callFake? You can still use but you need to define multiple returnValue methods based on total arguments needs to be tested.