简体   繁体   English

如何在单元测试中模拟RequireJs loader插件响应

[英]How can I mock RequireJs loader plugin responses in unit tests

The code I'm trying to test relies on RequireJs loader plugins . 我要测试的代码依赖RequireJs 加载程序插件 Example with requirejs/text : requirejs / text的示例:

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

For a specific unit test, I'm trying to mock the response for text!templates/foo and override with one relevant for the test: 对于特定的单元测试,我正在尝试模拟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();
  });

});

I've looked at RequireJs dependency mock solutions , especially Squire.js but it seems they are all suited for mocking regular dependencies and not plugin responses. 我看过RequireJs依赖模拟解决方案 ,尤其是Squire.js,但似乎它们都适合模拟常规依赖而不是插件响应。

I've also looked at stub libraries like sinon to maybe replace the actual require call but that seems problematic. 我还查看了诸如sinon之类的存根库,以替换实际的require调用,但这似乎有问题。

What's the recommended practice? 推荐的做法是什么? I prefer not to replace the entire text plugin with a mock one in my requirejs configuration, just override some of its responses in specific tests. 我宁愿不要在我的requirejs配置中用一个模拟插件替换整个text插件,而只是在特定测试中覆盖其某些响应。

My setup is node+mocha+requirejs 我的设置是node + mocha + requirejs

Edit 编辑

Please see this example fiddle project to see my issue with Squire: 请参阅以下示例小提琴项目,以查看我的Squire问题:

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

This will mock what you'd get from requiring text!foo/x.html . 这将模拟您从需要text!foo/x.html会得到的text!foo/x.html Plugins are not special, you just need to mock the entire path, including the plugin name. 插件并不特殊,您只需要模拟整个路径,包括插件名称。

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");
});

The problem you run into with the example code you added to your question is that you use the global require instead of using a require passed by your loader. 你碰到与你添加到您问题的示例代码的问题是,你使用全局require ,而不是使用require通过你的装载机通过。 You should add require as a dependency: 您应该添加require作为依赖项:

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

The require module is special and reserved by RequireJS. require模块是特殊的,由RequireJS保留。 It returns a reference to the require function. 它返回对require函数的引用。 You must use it, for instance, when you use RequireJS's contexts so that a module loaded in a specific context uses a require function that is bound to that context. 例如,当您使用RequireJS的上下文时,必须使用它,以便在特定上下文中加载的模块使用绑定到该上下文的require函数。 SquireJS also needs you to do this so that it can trap your calls to require . SquireJS还需要您执行此操作,以便它可以捕获对require的调用。 The global require bypasses SquireJS. 全局require绕过SquireJS。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM