我有以下ES6模块:
network.js
export function getDataFromServer() {
return ...
}
widget.js
import { getDataFromServer } from 'network.js';
export class Widget() {
constructor() {
getDataFromServer("dataForWidget")
.then(data => this.render(data));
}
render() {
...
}
}
我正在寻找一种使用的模拟实例测试Widget的方法getDataFromServer
。如果<script>
像Karma中那样使用单独的而不是ES6模块,则可以这样编写测试:
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模块(例如,使用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
并期望调用方提供dep。
export class Widget() {
constructor(deps) {
deps.getDataFromServer("dataForWidget")
.then(data => this.render(data));
}
}
我对这样弄乱Widget的公共接口并暴露实现细节感到非常不自在。不行
b。暴露导入以允许对其进行嘲笑。
就像是:
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();
});
});
这具有较小的侵入性,但是需要我为每个模块编写很多样板,而且仍然存在我可能会一直使用getDataFromServer
而不是deps.getDataFromServer
一直使用的风险。我对此感到不安,但这是到目前为止我最好的主意。
createSpy
(github.com/jasmine/jasmine/blob/…)函数,并从'network.js'模块导入对getDataFromServer的引用。这样,在小部件的测试文件中,您将导入getDataFromServer,然后将let spy = createSpy('getDataFromServer', getDataFromServer)
spyOn
从network.js
模块导入该对象。它始终是对同一对象的引用。
Widget
公共接口?Widget
被搞砸了没有 deps
。为什么不明确显示依赖性?