Normally, a spy exists for the lifetime of the spec. However, there's nothing special about destroying a spy. You just restore the original function reference and that's that.
Here's a handy little helper function (with a test case) that will clean up your workaround and make it more usable. Call the unspy
method in your afterEach
to restore the original reference.
function spyOn(obj, methodName) {
var original = obj[methodName];
var spy = jasmine.getEnv().spyOn(obj, methodName);
spy.unspy = function () {
if (original) {
obj[methodName] = original;
original = null;
}
};
return spy;
}
describe("unspy", function () {
it("removes the spy", function () {
var mockDiv = document.createElement("div");
var mockResult = $(mockDiv);
spyOn(window, "$").and.returnValue(mockResult);
expect($(document.body).get(0)).toBe(mockDiv);
$.unspy();
expect(jasmine.isSpy($)).toEqual(false);
expect($(document.body).get(0)).toBe(document.body);
});
});
As an alternative to the above (and for anyone else reading this), you could change the way you're approaching the problem. Instead of spying on the $
function, try extracting the original call to $
to its own method and spying on that instead.
// Original
myObj.doStuff = function () {
$("#someElement").css("color", "red");
};
// Becomes...
myObj.doStuff = function () {
this.getElements().css("color", "red");
};
myObj.getElements = function () {
return $("#someElement");
};
// Test case
it("does stuff", function () {
spyOn(myObj, "getElements").and.returnValue($(/* mock elements */));
// ...
});
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…