【问题标题】:Mocha: Can't seem to call module's methods that use jQuery from inside mocha testsMocha:似乎无法从 mocha 测试内部调用使用 jQuery 的模块方法
【发布时间】:2016-11-28 16:20:45
【问题描述】:

所以,我正在使用 Mocha/Chai 进行一些测试,而我正在测试的项目依赖于 jQuery。我正在使用 jsdom 来帮助解决这个问题。正如您从下面的代码中看到的那样我在 mocha 测试本身中使用 jQuery 没有问题。我似乎无法找到只是调用使用 jQuery 的代码。

在浏览器中运行时,jQuery 包含在脚本标记中,然后包含 ACE_GA 模块,因此 jQuery 完全可以在那里工作。

在检查下面的代码 sn-p 时,done() 函数中有两行带有 cmets。第一行有注释,只是调用了 ACE_GA 模块中的代码,它不起作用。有注释的第二行是从 ACE_GA 模块内部重新创建一些代码(我试图在第一行调用),它工作得很好。

要清楚,行得通的:

var productItems = jQuery("[data-" + ACE_GA.VALID_PRODUCT_FIELDS.prefix + "]");

只是从我试图调用的模块方法中复制一行,这给我带来了问题:

var productItems = ACE_GA.HELPERS.validateOptions(ACE_GA.VALID_PRODUCT_FIELDS.prefix);

我需要做什么才能简单地调用客户端库/模块并让 jQuery 使用它,而不是从模块复制/粘贴代码 sn-ps 到 mocha 测试中?

var chai = require("chai");
var jsdom = require("jsdom");
var jQuery = require("jquery");
var fs = require("fs");
var ACE_GA = require("../main");

var bodyContent = fs.readFileSync(__dirname + "/../test/test.html", "utf8", "r");
global.document = jsdom.jsdom(bodyContent);
global.window = document.defaultView;
global.jQuery = jQuery;

describe("ACE_GA.HELPERS.validateOptions", function() {

    it("should select all items with a data-attribute of 'ace-ga-{something}'", function(done) {

        jsdom.env({
            html: bodyContent,
            src: jQuery,
            scripts: "http://www.asite.com/path/to/default/js/jquery-1.11.3.min.js",
            userAgent: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36",
            done: function(err, window) {

                console.log("err", err);
                var jQuery = window.jQuery;

                //var productItems = ACE_GA.HELPERS.validateOptions(ACE_GA.VALID_PRODUCT_FIELDS.prefix);
                /** ^ that won't work and says jQuery requires a window with a document */

                var productItems = jQuery("[data-" + ACE_GA.VALID_PRODUCT_FIELDS.prefix + "]");
                /** ^ that works just fine and is copy/pasted from the non working method I'm trying to call above */

                chai.expect(productItems.length).to.equal(4);
                done();
            }
        });

    });

});

供任何人参考,这是我得到的失败错误的确切输出

1) ACE_GA.HELPERS.validateOptions should select all items with a data-attribute of 'ace-ga-{something}':
 Uncaught Error: jQuery requires a window with a document
  at module.exports (C:\Path\To\Project\dev-files\node_modules\jquery\dist\jquery.js:29:12)
  at Object.validateOptions (main.js:144:15)
  at Object.done (test\gaecTest.js:89:39)
  at process.nextTick (C:\Path\To\Project\dev-files\node_modules\jsdom\lib\jsdom.js:320:18)
  at _combinedTickCallback (internal/process/next_tick.js:67:7)
  at process._tickCallback (internal/process/next_tick.js:98:9)

据我所见,在包含的模块本身 (ACE_GA) 中,jQuery 的工作存在问题,因为我希望它自己从该上下文中工作(例如在 mocha 中定义然后调用 jQuery() 是可以的,但定义 jQuery () 在 mocha 中然后从 ACE_GA 模块内部调用它不起作用)。

如前所述,当在浏览器中运行它时,我可以在 before 中定义/包含 jQuery,包括 ACE_GA 模块。

我只是在这里尝试做类似的事情,而不是在浏览器中运行它,而是从带有 mocha 的节点运行它。

【问题讨论】:

    标签: javascript jquery mocha.js chai jsdom


    【解决方案1】:

    您遇到麻烦的直接原因是您没有正确初始化直接在节点中加载的 jQuery 实例(与您在 jsdom 实例中加载的相反)。

    当您执行require('jquery') 时,jQuery 会检查全局范围内是否存在document。如果是这样,它将自己安装在全局范围内。在浏览器中,结果是它将自己安装在window 上,如$jQuery。在 Node.js 中,默认情况下在全局范围内没有document。您显示的代码也是这种情况。当没有定义document 时,您从require('jquery') 获得的是一个工厂,您可以从中构建一个jQuery 实例。您必须将 Window 实例传递给该工厂。

    您可以将初始代码更改为:

    var chai = require("chai");
    var jsdom = require("jsdom");
    var makeJQ = require("jquery"); // Load the factory.
    var fs = require("fs");
    
    var bodyContent = fs.readFileSync(__dirname + "/../test/test.html", "utf8", "r");
    global.document = jsdom.jsdom(bodyContent);
    global.window = document.defaultView;
    global.$ = global.jQuery = makeJQ(window); // Actually make a jQuery instance.
    
    // Load this after, since it depends on jQuery being in the global space.
    var ACE_GA = require("../main");
    

    然后,您应该放弃在测试中使用 jsdom 创建的第二个窗口,而只使用在测试文件开头设置的窗口。您可以通过清理测试之间的 DOM 树来在测试之间重用它。

    【讨论】:

    • 哇!非常感谢!!
    • 我还在看Error: jQuery requires a window with a document
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-01
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2017-06-20
    相关资源
    最近更新 更多