在jasmine上监视jQuery $(’…’)选择器

当涉及监视jQuery函数(例如bindclick等)时,很容易:

 spyOn($.fn, "bind"); 

问题是当你想窥探$('...')并返回已定义的元素数组时。

在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 

那我该怎么做? 或者,如果唯一的方法是监视init函数,那么当我完成后如何从函数中“删除”间谍, afterEach()路由不会中断。

jQuery版本是1.9.1。

解决方法:

到目前为止我唯一可以使它工作的方式(丑陋):

 realDollar = $; try { $ = jasmine.createSpy("dollar").andReturn(elements); // test code and asserts go here } finally { $ = realDollar; } 

通常情况下,间谍存在于规范的生命周期中。 然而,摧毁间谍并没有什么特别之处。 您只需恢复原始函数引用即可。

这是一个方便的小助手function(带有测试用例),可以清理你的解决方法并使其更加实用。 在unspy中调用unspy方法以恢复原始引用。

 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); }); }); 

作为上述(以及其他任何阅读此内容)的替代方法,您可以改变接近问题的方式。 而不是监视$函数,尝试将原始调用$压缩到自己的方法,然后监视它。

 // 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就是其中之一,您可以轻松地在下面模拟它并返回您需要的值。

 spyOn(window, '$').and.returnValue(mockElement); 

或者如果需要是动态的,请在输入中添加callFake。