ฉันมีโมดูล 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
ทำไมไม่ทำให้การพึ่งพาชัดเจน?