How do we clear the spy in a jasmine test suite programmatically? Thanks.
beforeEach(function() {
spyOn($, \"ajax\").andCallFake(function(params){
})
})
In Jasmine 2, the spy state is held in a SpyStrategy instance.
You can get hold of this instance calling $.ajax.and
.
See the Jasmine source code on GitHub.
So, to set a different fake method, do this:
$.ajax.and.callFake(function() { ... });
To reset to the original method, do this:
$.ajax.and.callThrough();
I think that's what .reset() is for:
spyOn($, 'ajax');
$.post('http://someUrl', someData);
expect($.ajax).toHaveBeenCalled();
$.ajax.calls.reset()
expect($.ajax).not.toHaveBeenCalled();
From jasmine 2.5, you can use this global setting to update a spy within your test cases:
jasmine.getEnv().allowRespy(true);
Or you can do it
describe('test', function() {
var a, c;
c = 'spy1';
a = {
b: function(){}
};
beforeEach(function() {
spyOn(a, 'b').and.callFake(function () {
return c;
});
})
it('should return spy1', function() {
expect(a.b()).toEqual('spy1');
})
it('should return spy2', function() {
c = 'spy2';
expect(a.b()).toEqual('spy2');
})
})
In this case you use the same Spy but just change the var that it will return..
I'm not sure if its a good idea but you can simply set the isSpy
flag on the function to false:
describe('test', function() {
var a = {b: function() {
}};
beforeEach(function() {
spyOn(a, 'b').andCallFake(function(params) {
return 'spy1';
})
})
it('should return spy1', function() {
expect(a.b()).toEqual('spy1');
})
it('should return spy2', function() {
a.b.isSpy = false;
spyOn(a, 'b').andCallFake(function(params) {
return 'spy2';
})
expect(a.b()).toEqual('spy2');
})
})
But maybe its a better idea to create a new suite for this case where you need an other behavior from your spy.
I'm posting this answer to address the comment in OP @Tri-Vuong's code - which was my main reason for my visiting this page:
I want to override the spy ... here and do it a little differently
None of the answers so far address this point, so I'll post what I've learned and summarize the other answers as well.
@Alissa called it correctly when she explained why it is a bad idea to set isSpy
to false
- effectively spying on a spy resulting in the auto-teardown behavior of Jasmine no longer functioning as intended. Her solution (placed within the OP context and updated for Jasmine 2+) was as follows:
beforeEach(() => {
var spyObj = spyOn(obj,'methodName').and.callFake(function(params){
}) // @Alissa's solution part a - store the spy in a variable
})
it("should do the declared spy behavior", () => {
// Act and assert as desired
})
it("should do what it used to do", () => {
spyObj.and.callThrough(); // @Alissa's solution part b - restore spy behavior to original function behavior
// Act and assert as desired
})
it("should do something a little differently", () => {
spyObj.and.returnValue('NewValue'); // added solution to change spy behavior
// Act and assert as desired
})
The last it
test demonstrates how one could change the behavior of an existing spy to something else besides original behavior: "and
-declare" the new behavior on the spyObj previously stored in the variable in the beforeEach()
. The first test illustrates my use case for doing this - I wanted a spy to behave a certain way for most of the tests, but then change it for a few tests later.
For earlier versions of Jasmine, change the appropriate calls to .andCallFake(
, .andCallThrough()
, and .andReturnValue(
respectively.