在jasmine上监视jQuery $('...')选择器

时间:2014-02-27 05:50:38

标签: javascript jquery unit-testing mocking jasmine

当涉及监视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;
}

2 个答案:

答案 0 :(得分:8)

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

这是一个方便的小助手功能(带有测试用例),可以清理你的解决方法并使其更有用。调用unspy中的afterEach方法恢复原始参考。

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 */));
    // ...
});

答案 1 :(得分:1)

通过监视窗口本身,您可以访问任何窗口属性。 由于Jquery就是其中之一,您可以轻松地在下面模拟它并返回您需要的值。

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

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