ฉันมีโมดูล 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>s แยกต่างหากจากโมดูล ES6 เช่นเดียวกับใน 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 แยกจากเบราว์เซอร์ (เช่นกับ 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และคาดว่าผู้โทรจะให้รายละเอียด
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();
});
});
นี่เป็นการรุกรานน้อยกว่า แต่ต้องให้ฉันเขียนจำนวนมากในแต่ละโมดูลและยังมีความเสี่ยงที่ฉันจะใช้getDataFromServerแทนdeps.getDataFromServerตลอดเวลา ฉันไม่สบายใจเกี่ยวกับเรื่องนี้ แต่นั่นเป็นความคิดที่ดีที่สุดของฉันจนถึงตอนนี้
createSpy( github.com/jasmine/jasmine/blob/… ) พร้อมการอ้างอิงที่นำเข้าสู่ getDataFromServer จากโมดูล 'network.js' ดังนั้นในไฟล์ทดสอบของวิดเจ็ตที่คุณจะต้องนำเข้า getDataFromServer และจากนั้นก็จะlet spy = createSpy('getDataFromServer', getDataFromServer)
spyOnบนวัตถุนั้นซึ่งนำเข้าจากnetwork.jsโมดูล มันเป็นการอ้างอิงถึงวัตถุเดียวกันเสมอ
Widgetอินเตอร์เฟซสาธารณะได้อย่างไร Widgetเป็น messed up โดยไม่ต้อง depsทำไมไม่ทำให้การพึ่งพาชัดเจน?