由于导入ES6模块会为您提供该模块的只读视图,因此模拟它会产生错误'x' is read-only
。这使我无法通过破坏其依赖关系来隔离被测代码。我不知道怎么解决这个问题。
http://exploringjs.com/es6/ch_modules.html
*我会抛出一个Plunker,但我无法识别import
语句,而JSFiddle似乎不允许其他文件,这本来是导出的模块。
答案 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 是一种可行的方法,因为它在单独的过程中加载每个规范,使一个规范不会干扰另一个规范,因此这种模拟方法变得可行。