如果它们是只读的,我如何模拟ES6导入的模块?

时间:2017-01-02 20:07:19

标签: javascript unit-testing import ecmascript-6

由于导入ES6模块会为您提供该模块的只读视图,因此模拟它会产生错误'x' is read-only。这使我无法通过破坏其依赖关系来隔离被测代码。我不知道怎么解决这个问题。

http://exploringjs.com/es6/ch_modules.html

*我会抛出一个Plunker,但我无法识别import语句,而JSFiddle似乎不允许其他文件,这本来是导出的模块。

2 个答案:

答案 0 :(得分:0)

我的解决方案是改变我的导出方式。如果我导出属性对象而不是单独的属性本身,我不会得到错误。这似乎是因为Object.freeze只有一层深度,所以导出的对象被冻结,但不是儿童。

import {ua} from './index';

./index.js导出一个命名对象,其中包含我要覆盖的道具:



export const ua = {
    deleteUser,
    loadUsers
};




这允许我的测试代码中包含以下内容:



ua.loadUsers = function () {
           expect(delUspy.calledOnce).toBe(true);
           expect(loadUspy.callCount).toEqual(1);
           done();
        };




...但是ua = {}因为被冻结而失败了。

答案是导出道具的对象,并避免导入单个属性。

答案 1 :(得分:0)

如果您正在使用 sinon,我的建议是停止使用它。他们不支持模拟只读模块并且对这个话题非常激进 https://github.com/sinonjs/sinon/issues/1711

另一方面,使用 jest,您可以轻松模拟 ES6 只读模块,如下所示:

const myMockedModule = {
   ...jest.requireActual('my-es6-readonly-module'),
   theFunctionIWantToMock: jest.fn(),
}
jest.mock('my-es6-readonly-module', () => myMockedModule);

您需要将其作为规范的第一行。使用这种方法,您可以模拟从任何模块直接导出的项目,即使它是只读的,因为 jest 会拦截 require 方法。 这对于 mocha 也不太可行,因为 mocha 在同一进程中加载​​所有测试,而其他一些测试套件可能会直接或间接加载您想要模拟的模块,这会破坏您的测试. Jest 是一种可行的方法,因为它在单独的过程中加载每个规范,使一个规范不会干扰另一个规范,因此这种模拟方法变得可行。