Javascript 监视jasmine中的jQuery$(';…';)选择器

Javascript 监视jasmine中的jQuery$(';…';)选择器,javascript,jquery,unit-testing,mocking,jasmine,Javascript,Jquery,Unit Testing,Mocking,Jasmine,当涉及到监视jQuery函数时(例如,bind,单击,等等),很容易: spyOn($.fn, "bind"); 问题是当您想要监视$(“…”)并返回定义的元素数组时 在阅读其他相关答案后尝试过的事情,因此: spyOn($.fn, "init").andReturn(elements); // works, but breaks stuff that uses jQuery selectors in afterEach(), etc spyOn($.fn, "merge").andRetur

当涉及到监视jQuery函数时(例如,
bind
单击
,等等),很容易:

spyOn($.fn, "bind");
问题是当您想要监视
$(“…”)
并返回定义的元素数组时

在阅读其他相关答案后尝试过的事情,因此:

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

解决方法:

到目前为止,我唯一能让它工作的方法(丑陋):


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

这里有一个方便的小助手函数(带有一个测试用例),它将清理您的工作环境并使其更可用。每次后调用
中的
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 */));
    // ...
});

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

这里有一个方便的小助手函数(带有一个测试用例),它将清理您的工作环境并使其更可用。每次
后调用
中的
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。

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

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

或者在需要动态输入的情况下添加callFake。

这是一个只需代码的答案。仅代码的答案可能有效,但会自动标记为低质量。请添加一个简短的解释,说明此代码为什么工作,或者错误是什么-这是一个代码唯一的答案。仅代码的答案可能有效,但会自动标记为低质量。请添加一个简短的解释,说明此代码为什么工作,或者错误是什么-