mikhail
mikhail

Reputation: 5169

How to have different return values for multiple calls on a Jasmine spy

Say I'm spying on a method like this:

spyOn(util, "foo").andReturn(true);

The function under test calls util.foo multiple times.

Is it possible to have the spy return true the first time it's called, but return false the second time? Or is there a different way to go about this?

Upvotes: 143

Views: 99481

Answers (2)

Ocean
Ocean

Reputation: 2942

You can use spy.and.returnValues (as Jasmine 2.4).

for example

describe("A spy, when configured to fake a series of return values", function() {
  beforeEach(function() {
    spyOn(util, "foo").and.returnValues(true, false);
  });

  it("when called multiple times returns the requested values in order", function() {
    expect(util.foo()).toBeTruthy();
    expect(util.foo()).toBeFalsy();
    expect(util.foo()).toBeUndefined();
  });
});

However, there is something you must be careful about. There is another function with a similar spelling: returnValue without s. If you use that, Jasmine will not warn you, but it will behave differently.

Upvotes: 239

voithos
voithos

Reputation: 70552

For older versions of Jasmine, you can use spy.andCallFake for Jasmine 1.3 or spy.and.callFake for Jasmine 2.0, and you'll have to keep track of the 'called' state, either through a simple closure, or object property, etc.

var alreadyCalled = false;
spyOn(util, "foo").andCallFake(function() {
    if (alreadyCalled) return false;
    alreadyCalled = true;
    return true;
});

Upvotes: 32

Related Questions