问题
I have an angular controller with a method that calls $location.search()
twice.
First time is just $location.search()
to return the value.
Second time is $location.search("foo", null)
to clear it.
I have the following spy in my unit test:spyOn($location, "search").and.returnValue({ foo: "bar" });
It appears the spy returns {foo:"bar"}
even when my implementation does $location.search("foo", null)
.
I need a way to have two different spies for the same method depending on the arguments.
I need this expect:expect($location.search().foo).toEqual(null);
to pass at the end of the unit test.
回答1:
You can go about it different ways. If you have time to change the spy implementation during your testcase, you can do this:
var searchSpy = spyOn($location,'search');
searchSpy.and.returnValue(null);
// do stuff
searchSpy.and.returnValue({ foo: "bar" });
// do other stuff
If the calls are triggered by a method in your code, and you cannot change the spy implementation in between, then you can create a function that takes the arguments and responds appropriately:
spyOn($location,'search').and.callFake(function(someParam){
if (someParam) {
return { foo: "bar" };
} else {
return { foo: null };
}
});
Of course you can go crazy with logic in your callFake implementation, but beware, I think in that case it might be a code smell. Anyway, happy coding!
回答2:
Also it's possible to call spy properties on the mocked object directly. The code may look like:
spyOn($location,'search');
$location.search.and.returnValue(null);
// do stuff
$location.search.and.returnValue({ foo: "bar" })
// do other stuff
In case of typescript it may look like:
spyOn($location,'search');
(<jasmine.Spy>$location.search).and.returnValue(null);
// do stuff
(<jasmine.Spy>$location.search).and.returnValue({ foo: "bar" })
// do other stuff
Posting this answer because it may look a bit cleaner and doesn't require additional variables.
来源:https://stackoverflow.com/questions/36200532/jasmine-spyon-same-method-more-than-once