How to have different return values for multiple calls on a Jasmine spy
Solution 1
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();
});
});
There is some thing you must be careful about, there is another function will similar spell returnValue
without s
, if you use that, jasmine will not warn you.
Solution 2
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;
});
![mikhail](https://i.stack.imgur.com/DrLXZ.jpg?s=256&g=1)
mikhail
Software Engineer Spent a few years doing embedded work, but currently developing my JavaScript skills.
Updated on July 08, 2022Comments
-
mikhail about 2 years
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 returnfalse
the second time? Or is there a different way to go about this? -
Jack about 8 yearsWe can extend this for more than 2 calls like so: var results = [true, false, "foo"]; var callCount = 0; spyOn(util, "foo").and.callFake(function() { return results[callCount++]; });
-
The DIMM Reaper about 8 years+1: this is an excellent feature. A word of warning, though - be careful not to forget the 's' in
.returnValues
- the two functions are obviously different, but passing multiple arguments to.returnValue
doesn't throw an error. I don't want to admit how much time I wasted due to that one character. -
Tomas Lieberkind almost 8 yearsThis can be extended into a generic function like so: function returnValues() { var args = arguments; var callCount = 0; return function() { return args[callCount++]; }; }
-
Ocean over 7 years@TheDIMMReaper, Thank you. I mention it now.
-
ThaFog over 5 yearsWhy whole this code when you can just return results.shift() ?
-
Ian over 5 yearsDoing it in the beforeEach was important for me, not in the test (it)
-
Lijo about 5 yearshow about when we return observabvles
-
Elliott Beach almost 5 yearsNo need to worry about spelling errors when using jasmine in TypeScript, of course.
-
0bj3ct about 4 yearsthis option is more flexible, as we can throw error or return value depending on the call order.