将 nock 与 Intern4 和 dojo 一起使用 - 正确的方法是什么

Using nock with Intern4 and dojo - What is the correct approach

我一直在尝试使用 Intern 作为我们代码库的测试平台,它有很多奇怪的地方。我们基本上在 dojoLoader 和核心 dojo 文件之外加载。这意味着我们在发布过程之外,并且在测试带来的内容方面失去了所有优点。

我承担了开发工具链的任务,该工具链将管理代码(linting、构建)并最终进行测试。而且我必须掌握单元测试和功能测试的大部分方面,但是测试第 3 方 APIs 真的让我摸不着头脑。

阅读文档后,我应该能够使用 Nock 来模拟 api,我尝试了许多不同的示例来获得基本的 hello world 工作,并且我取得了不同程度的成功。

我注意到的是,当您在本机使用节点时,Nock 似乎可以很好地发挥作用,但是一旦将 dojo 引入等式,它就会崩溃。我尝试过使用 axiosgettddbdd。所有这些似乎都惨遭失败。

下面的代码让我有了突破性的时刻,这将使我能够成功地使用 Nock 测试模拟 API。

我看到其他示例采用 TDD 方法,但是当我使用 define 模式时,没有 done() 表示异步过程已完成。

虽然下面的确实有效,但我觉得我不得不跳过很多环节才能达到这一点,即缺少核心节点模块util.promisify(我目前运行 Node V9.10.x).缺乏对 import 等人的支持,所有这些都使得采用示例非常困难。

我是实习生的新手,我想知道是否有我缺少的首选或标准方法可以使这更简单。老实说,我更喜欢视觉上的 TDD/BDD 模式,但如果下面是我设置的唯一选择,那么我会接受。

define([
    'require',
    'dojo/node!nock',
    'dojo/node!http',
    'dojo/node!es6-promisify'
], function (require, nock, http, util) {
    const { registerSuite } = intern.getInterface('object');
    const { assert } = intern.getPlugin('chai');

    const { get } = http;
    const { promisify } = util;
    const _get = promisify(get);

    registerSuite('async demo', {
        'async test'() {
            const dfd = this.async();

            nock('http://some-made-up-service.com')
                .get('/request')
                .reply(200, {a:'Hello world!'});

            http.request({
                host:'some-made-up-service.com',
                path: '/request',
                port: 80
            }, function(res){
                res.on('data', dfd.callback((data) => {
                    var toJSON = JSON.parse(data.toString())
                    assert.strictEqual(toJSON.a, 'Hello world!');
                }))
            }).end();
        }
    });
});

我的配置也在这里,我确定文件中有一些不必要的条目,但我只是想弄清楚目前的工作原理。

{
    "node": {
        "plugins": "node_modules/babel-register/lib/node.js"
    },
    "loader": {
        "script": "dojo",
        "options": {
            "packages": [
                { "name": "app", "location": "asset/js/app" },
                { "name": "tests", "location": "asset/js/tests" },
                { "name": "dojo", "location": "node_modules/dojo" },
                { "name": "dojox", "location": "node_modules/dojox" },
                { "name": "dijit", "location": "node_modules/dijit" }
            ],
            "map": {
                "plugin-babel": "node_modules/systemjs-plugin-babel/plugin-babel.js",
                "systemjs-babel-build": "node_modules/systemjs-plugin-babel/systemjs-babel-browser.js"
            },
            "transpiler": "plugin-babel"
        }
    },
    "filterErrorStack": false,
    "suites": [
        "./asset/js/common/sudo/tests/all.js"
    ],
    "environments": ["node", "chrome"],
    "coverage": "asset/js/common/sudo/dev/**/*.js"
}

如果您正在使用 dojo 的请求方法,则可以使用 Dojo 的 request registry to setup mocking,在使用 Dojo 时,它比 nock 更容易处理。不过,总的来说,该过程将与您的示例中的过程类似:模拟请求、发出请求、在请求完成并做出断言时异步解决测试。

关于 util.promisify,它存在于 Node v8+ 中,因此您应该能够在 9.10 中使用它。

关于 tdd 与 bdd,假设您指的是 Intern 测试接口(尽管听起来您可能指的是其他东西?),它们都支持相同的功能集。如果你可以用 "object" 接口(registerSuite)做一些事情,你也可以用 "tdd"(suitetest)和 "bdd"(describeit)接口。

关于缺少对 import 和其他语言功能的支持,这取决于测试的编写方式,而不是 Intern 的功能。如果测试需要在 Dojo 加载器中 运行,它们将需要是 AMD 模块,这意味着没有 import。然而,测试可以通过 TypeScript 编译器或 babel 用现代 ES6 和 运行 编写,并作为 AMD 模块发出。这增加了一个构建步骤,但至少可以用更现代的语法编写测试。

请注意,node-specific 功能(nock、promisify 等)无法在浏览器中运行。