jasmine: Is this the only difference between returnValue and callFake?

callFake(() => {...}) takes a call back function

  1. If we just want a return value when a service method is called then we can use any of and.callFake or and.returnValue

component file:

@Component(...)
export class DependencyComponent {
  constructor(private service: RandomService){....}
  .....
  sampleMethod() {
   return this.service.randomMethod();
  }
  .....
}

unit test case for above component:

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.

  1. 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:

@Component(...)
export class DependencyComponent {
  constructor(private service: RandomService){....}
  .....
  sampleMethod(val) {
  return this.service.randomMethod(val);
  }
  .....
}

unit test case for above component:

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.