【问题标题】:How can I mock RequireJs loader plugin responses in unit tests如何在单元测试中模拟 RequireJs 加载器插件响应
【发布时间】:2015-07-06 21:11:01
【问题描述】:

我尝试测试的代码依赖于 RequireJs loader plugins。以requirejs/text 为例:

require(['text!templates/foo'], function (data) {
  // handle loaded data
});

对于特定的单元测试,我正在尝试模拟text!templates/foo 的响应并用与测试相关的响应覆盖:

it('should load a template', function (done) {

  // TODO: mock 'text!templates/foo' here to return 'mock_data'

  // templateViewer uses the text plugin internally to do the actual loading
  templateViewer.templateFor('foo', function (error, templateData) {
    expect(templateData).toEqual('mock_data');
    done();
  });

});

我查看了 RequireJs 依赖项模拟 solutions,尤其是 Squire.js,但似乎它们都适合模拟常规依赖项而不是插件响应。

我还查看了像 sinon 这样的存根库,可能会替换实际的 require 调用,但这似乎有问题。

推荐的做法是什么?我不想在我的 requirejs 配置中用模拟插件替换整个 text 插件,只是在特定测试中覆盖它的一些响应。

我的设置是node+mocha+requirejs

编辑

请查看此示例小提琴项目以了解我与 Squire 的问题:

http://runnable.com/VUBoI0ex6v9Gs-BJ/squirejs-with-plugins-for-node-js-and-hello-world

【问题讨论】:

    标签: javascript unit-testing mocking requirejs squirejs


    【解决方案1】:

    这将模拟您从要求 text!foo/x.html 中得到的结果。插件并不特殊,你只需要模拟整个路径,包括插件名称。

    var requirejs = require("requirejs");
    var assert = require("assert");
    
    requirejs.config({
        baseUrl: __dirname,
        packages: [
            {
                name: "squire",
                location: "node_modules/squirejs",
                main: "src/Squire"
            }
        ]
    });
    
    var x;
    before(function (done) {
        requirejs(["squire"], function (Squire) {
            var injector = new Squire();
    
            injector.mock("text!foo/x.html", "foo").require(["text!foo/x.html"],
                                                       function (_x) {
                x = _x;
                done();
            });
        });
    });
    
    it("foo", function () {
        assert.equal(x, "foo");
    });
    

    您添加到问题中的示例代码遇到的问题是您使用全局require 而不是使用加载程序传递的require。您应该添加 require 作为依赖项:

    define(['require', ....], function (require, ....) {
    

    require 模块是特殊的,由 RequireJS 保留。它返回对require 函数的引用。例如,当您使用 RequireJS 的上下文时,您必须使用它,以便在特定上下文中加载的模块使用绑定到该上下文的 require 函数。 SquireJS 也需要你这样做,以便它可以捕获你对require 的调用。全局 require 绕过 SquireJS。

    【讨论】:

    • 试过了,因为插件与 require() 而不是 define() 一起使用,所以无法正常工作。请看这个例子小提琴:runnable.com/VUBoI0ex6v9Gs-BJ/…
    • “不工作?”我在答案中输入的代码已经过测试并且运行良好。
    • 看看我发布的runnable。您的代码当然可以完美运行,但我的用例略有不同。可运行文件显示了差异。
    • 你,我的朋友,真棒!谢谢一百万,我完全错过了在 RequireJs 文档中传递要求的部分
    猜你喜欢
    • 2012-07-11
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    相关资源
    最近更新 更多