如何使用mocha/chai模拟窗口/文档

Jea*_*eri 22 javascript unit-testing mocha.js node.js

当我尝试单元测试getElement功能时

class BarFoo {
    getElement() {
        return document.querySelector('#barfoo');
    }
}
Run Code Online (Sandbox Code Playgroud)

摩卡什么都不知道document,所以我想你可能会这样做:

beforeEach(() => {
    global.document = {
        querySelector: () => { ... }
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然这有效,但我想知道这是否是正确的方法,并且可能有一个包可以解决这个问题,因为如果使用更多的浏览器API,我的方法会变得费力?

Jer*_*her 17

有几种选择:

选项1:使用JSDOM

通过在代码中添加DOM,您可以在node.js中对大部分客户端代码进行单元测试

选项2:在客户端上使用MOCHA

Mocha确实在客户端内部运行,您可以使用单独的客户端单元测试.这往往是我的首选方法,因为我可以针对特定的浏览器进行测试,而不是特定的JS植入.

选项3:使用PhantomJS

PhantomJS允许您在测试环境中控制无头浏览器.

选项4:无头Chrome

现在无头Chrome已经推出,PhantomJS维护人员已经退休了.

  • @LeeGee“重要:PhantomJS开发被暂停,直到另行通知(更多详细信息)。” -当有其他可用选项时,我不建议您不再维护的软件包。 (2认同)

Sim*_*son 15

当我只需要在窗口上模拟某个函数时,我一直在编写类似于你提出的测试:

it('html test', function () {
    const windowRef = global.window;
    global.window = {document: {querySelector: () => null}};
    const lib = require('lib-that-uses-queryselector');
    assert(true);
    global.window = windowRef;
});
Run Code Online (Sandbox Code Playgroud)

当我想要一个更完整的窗口对象时,我一直在其他测试中使用mock-browser:

it('html test', function () {
     const windowRef = global.window;
     const MockBrowser = require('mock-browser').mocks.MockBrowser;
     global.window = new MockBrowser().getWindow();
     const lib = require('lib-that-uses-window');
     assert(true);
     global.window = windowRef;
});
Run Code Online (Sandbox Code Playgroud)

请注意,您可能希望global.window = windowRef;弄乱全局变量后恢复窗口对象(上面).

  • @SimonBengtsson,`global.window = window`不会恢复寡妇对象,因为使用`window = global.window`创建的窗口常量是通过引用复制的。相反,您可以使用以下命令克隆测试顶部的窗口:“preservedWindow = Object.assign({}, window)”,然后在完成测试后重新分配:“global.window =servedWindow”(请注意,由于 Object.分配仅进行浅复制,但在大多数情况下应该足够好) (2认同)