次の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() {
...
}
}
のモックインスタンスでウィジェットをテストする方法を探しています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
テスト可能にできますか?
私が考えたもの:
a。依存関係の手動注入。
からすべてのインポートを削除widget.js
し、呼び出し元がdepを提供することを期待します。
export class Widget() {
constructor(deps) {
deps.getDataFromServer("dataForWidget")
.then(data => this.render(data));
}
}
私はこのようにウィジェットの公開インターフェースをめちゃくちゃにして、実装の詳細を公開することに非常に不快です。立ち入り禁止。
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