我有以下 ES6 module:
文件network.js
export function getDataFromServer() {
return ...
}
文件小部件.js
import { getDataFromServer } from 'network.js';
export class Widget() {
constructor() {
getDataFromServer("dataForWidget")
.then(data => this.render(data));
}
render() {
...
}
}
我正在寻找一种方法来测试 Widget 的模拟实例getDataFromServer
。如果我使用单独的<script>
s 而不是 ES6 module,就像在 Karma 中一样,我可以像这样编写测试:
describe("widget", function() {
it("should do stuff", function() {
let getDataFromServer = spyOn(window, "getDataFromServer").andReturn("mockData")
let widget = new Widget();
expect(getDataFromServer).toHaveBeenCalledWith("dataForWidget");
expect(otherStuff).toHaveHappened();
});
});
但是,如果我在浏览器之外单独测试 ES6 module(例如使用Mocha + Babel),我会编写如下内容:
import { Widget } from 'widget.js';
describe("widget", function() {
it("should do stuff", function() {
let getDataFromServer = spyOn(?????) // How to mock?
.andReturn("mockData")
let widget = new Widget();
expect(getDataFromServer).toHaveBeenCalledWith("dataForWidget");
expect(otherStuff).toHaveHappened();
});
});
好的,但现在getDataFromServer
不可用window
(好吧,根本没有window
),而且我不知道如何将内容直接注入到widget.js
自己的作用域中。
那么我该去哪里呢?
- 有没有办法访问 的范围
widget.js
,或者至少用我自己的代码替换它的导入? - 如果没有,我该如何进行
Widget
测试?
我考虑过的东西:
一个。手动依赖注入。
删除所有导入widget.js
并期望调用者提供 deps。
export class Widget() {
constructor(deps) {
deps.getDataFromServer("dataForWidget")
.then(data => this.render(data));
}
}
我对像这样弄乱 Widget 的公共接口并暴露实现细节感到非常不舒服。不行。
湾 公开导入以允许模拟它们。
就像是:
import { getDataFromServer } from 'network.js';
export let deps = {
getDataFromServer
};
export class Widget() {
constructor() {
deps.getDataFromServer("dataForWidget")
.then(data => this.render(data));
}
}
然后:
import { Widget, deps } from 'widget.js';
describe("widget", function() {
it("should do stuff", function() {
let getDataFromServer = spyOn(deps.getDataFromServer) // !
.andReturn("mockData");
let widget = new Widget();
expect(getDataFromServer).toHaveBeenCalledWith("dataForWidget");
expect(otherStuff).toHaveHappened();
});
});
这是侵入性较小的,但它需要我为每个module编写大量样板,并且仍然存在我使用getDataFromServer
而不是deps.getDataFromServer
一直使用的风险。我对此感到不安,但这是我目前最好的主意。