Javascript 在节点环境中stubing jQuery.ajax(jquery2.x)

Javascript 在节点环境中stubing jQuery.ajax(jquery2.x),javascript,jquery,node.js,Javascript,Jquery,Node.js,我正在尝试运行一些需要stubingjQuery.ajax的测试。我正在使用SinonJS来实现这一点,它在较旧版本的jQuery(1.x)中运行良好 然而,在升级到jQuery2.x之后,当我需要模块中的jQuery运行时,我必须包含一个窗口环境。我正在使用jsdom来完成以下任务: var document = require('jsdom').jsdom(), window = document.parentWindow, $ = require('jquer

我正在尝试运行一些需要stubing
jQuery.ajax
的测试。我正在使用SinonJS来实现这一点,它在较旧版本的jQuery(1.x)中运行良好

然而,在升级到jQuery2.x之后,当我需要模块中的jQuery运行时,我必须包含一个窗口环境。我正在使用
jsdom
来完成以下任务:

var document = require('jsdom').jsdom(),
    window  = document.parentWindow,
    $       = require('jquery')(window);
问题
$。ajax
现在未定义。我怀疑是因为现在它返回绑定到特定元素的jQuery对象,但不完全确定。有人知道为什么和如何避开这个问题吗

EDIT我的一个朋友没有打开,所以他指出,如果我们将
窗口
附加到global,我们可以得到普通的jquery对象,而不是工厂

    global.window = require('jsdom').jsdom().parentWindow;
    var $ = require('jquery'); // this works as $.ajax is now defined

我不喜欢将window附加到global,因为它会影响一些类型为checkwindow的插件。我不是一个拦截器,但我很想看看是否有其他方法可以解决这个问题。

我可以发誓,在阅读jquery源代码之后,我在提出问题的那天尝试了这个方法,但没有成功。我刚才又试了一次,效果很好

tl;jQuery博士将$附加到浏览器模拟器的窗口命名空间

var document    = require('jsdom').jsdom(),
    window      = document.parentWindow;
require('jquery')(window);
var $ = window.$;

希望它对其他人有用。

虽然存根不错,但它们不如仿冒品好,而仿冒品不如仿制品好。我建议使用Sinon更有趣的功能来制造假货

您可以伪造
XMLHttpRequest
和或
XMLHttpResponse

var xhr, requests;

before(function () {
    xhr = sinon.useFakeXMLHttpRequest();
    requests = [];
    xhr.onCreate = function (req) { requests.push(req); };
});

after(function () {
    // Like before we must clean up when tampering with globals.
    xhr.restore();
});

it("makes a GET request for todo items", function () {
    getTodos(42, sinon.spy());

    assert.equals(requests.length, 1);
    assert.match(requests[0].url, "/todo/42/items");
});
或者你甚至可以模拟服务器

var server;

before(function () { server = sinon.fakeServer.create(); });
after(function () { server.restore(); });

it("calls callback with deserialized data", function () {
    var callback = sinon.spy();
    getTodos(42, callback);

    // This is part of the FakeXMLHttpRequest API
    server.requests[0].respond(
        200,
        { "Content-Type": "application/json" },
        JSON.stringify([{ id: 1, text: "Provide examples", done: true }])
    );

    assert(callback.calledOnce);
});

你可以很有创意,模仿超时、延迟、404、401。因为您仍将使用
JQuery.Ajax
对象库,在注入增强请求和响应的间谍的同时,您可以用更少的努力创建更真实、更健壮的测试,而不必去存根所有的可能性。

您有两种选择来在节点中执行请求:

1) 使用jquery

var $ = require('jquery')(require("jsdom").jsdom().parentWindow);
// now $.ajax works well
2) 带npm请求

3) 使用本机对象XHR


我测试了这三个选项,最后使用了package request(以避免额外的包,如jquery+jsdom),对于奇怪的情况,我使用原生XHR。

jsdom与io.js一起工作,而不是“不推荐”的环境(如node),因此可能您的后端更新会解决这个问题。@BenjaminGruenbaum我很乐意,我现在必须坚持使用node。我将jsdom绑定到3.x,这样就不会有问题了。你看到了吗?@BenjaminGruenbaum我看到了。问题已经定义了
$.ajax
。它只是不起作用。我没有将此函数绑定到jQuery对象。为什么要使用jQuery ajax?更简单。谢谢!我确实在代码的其他地方使用了假服务器和模拟服务器。对于更简单的测试,我只是将它们删除。快一点:)林,啊哈。那样的话,我的回答就没有必要了。你的需求只是句法上的。公平地说,这个问题写得有点糟糕。我与Sinon中的stubing无关,而与jQuery如何在2.x:D中更改其导出接口有关,但我非常感谢您抽出时间来编写答案。它确实解决了这个问题,虽然不是以我想要的方式来解决的^^^嘿,谢谢,但我正在使用在node上运行的工具测试客户机代码。我不是在测试服务器代码。而且你的选择1是错误的。请阅读问题
var $ = require('jquery')(require("jsdom").jsdom().parentWindow);
// now $.ajax works well