监视茉莉花中的jQuery $(' ...')选择器 [英] Spying on jQuery $('...') selector in jasmine
问题描述
在监视jQuery函数(例如 bind
, click
等)时,很容易:
spyOn($.fn,"bind");
问题是当您想监视 $('...')
并返回定义的元素数组时.
在阅读有关SO的其他相关答案后尝试过的事情:
spyOn($.fn,"init").andReturn(elements);//工作正常,但会破坏afterEach()等中使用jQuery选择器的内容spyOn($.fn,"merge").andReturn(elements);//合并功能似乎在jQuery 1.9.1中不存在spyOn($.fn,"val").andReturn(elements);//函数永远不会被调用
那我该怎么做呢?或者,如果唯一的方法是监视 init
函数,那么完成后如何从函数中删除"间谍,以使 afterEach()
路由不会中断./p>
jQuery版本是1.9.1.
解决方法:
到目前为止(我很难做到),这是我唯一的方法:
realDollar = $;尝试 {$ = jasmine.createSpy("dollar").andReturn(elements);//测试代码并断言此处} 最后 {$ = realDollar;}
通常,在规格有效期内存在间谍.但是,销毁间谍没有什么特别的.您只需恢复原始函数引用即可.
这里有一个方便的小助手功能(带有一个测试用例),它将清理您的解决方法并使其更有用.在 afterEach
中调用 unspy
方法以恢复原始引用.
function spyOn(obj,methodName){var original = obj [methodName];var spy = jasmine.getEnv().spyOn(obj,methodName);spy.unspy = function(){如果(原始){obj [methodName] =原始;原始= null;}};返回间谍}describe("unspy",function(){it(删除间谍",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);});});
作为上述替代方法(以及对所有其他阅读此方法的人而言),您可以更改解决问题的方式.与其侦听 $
函数,不如尝试将对 $
的原始调用提取到其自己的方法中,并以此侦听.
//原始myObj.doStuff = function(){$(#someElement").css("color","red");};//变成...myObj.doStuff = function(){this.getElements().css("color","red");};myObj.getElements = function(){返回$(#someElement");};//测试用例it("does stuff",function(){spyOn(myObj,"getElements").and.returnValue($(/*模拟元素*/));//...});
When it comes to spying on jQuery functions (e.g. bind
, click
, etc) it is easy:
spyOn($.fn, "bind");
The problem is when you want to spy on $('...')
and return defined array of elements.
Things tried after reading other related answers on SO:
spyOn($.fn, "init").andReturn(elements); // works, but breaks stuff that uses jQuery selectors in afterEach(), etc
spyOn($.fn, "merge").andReturn(elements); // merge function doesn't seem to exist in jQuery 1.9.1
spyOn($.fn, "val").andReturn(elements); // function never gets called
So how do I do this? Or if the only way is to spy on init
function how do I "remove" spy from function when I'm done so afterEach()
routing doesn't break.
jQuery version is 1.9.1.
WORKAROUND:
The only way I could make it work so far (ugly):
realDollar = $;
try {
$ = jasmine.createSpy("dollar").andReturn(elements);
// test code and asserts go here
} finally {
$ = realDollar;
}
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 */));
// ...
});
这篇关于监视茉莉花中的jQuery $(' ...')选择器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!