asolvent
asolvent

Reputation: 881

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

The only difference between callFake and returnValue is that callFake can return different values on the basis of custom logic (parameters/environment)?

Are there any other differences?

Upvotes: 10

Views: 8175

Answers (4)

Taher
Taher

Reputation: 752

I have observed a strange behavior and differece between returnValue and callFake in my Angular 8 code (with jasmine). Below is my code,

spyOn(object, 'method').and.returnValue(Promise.reject('error'));

When I have the above code, when I call tick() the above spy method gets invoked on its own - without calling the component method. That results in my test failing with error Uncaught promise error. However, when I change the above code to this,

spyOn(object, 'method').and.callFake(() => Promise.reject('error'));

the code work as expected and the spy method is called only when invoked from within the component.

Unable to understand what is the difference here and why callFake works.

Upvotes: 1

Abhishek
Abhishek

Reputation: 256

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.

Upvotes: 10

Shailesh kumar
Shailesh kumar

Reputation: 961

Clear difference or benefit can be seen when callfake has callback function as parameter .

Upvotes: 1

Sri
Sri

Reputation: 287

Both are same.. returnValue is just syntactical sugar over callfake is what I understand.

Upvotes: 0

Related Questions