Tôi có các mô-đun ES6 sau:
mạng.js
export function getDataFromServer() {
return ...
}
widget.js
import { getDataFromServer } from 'network.js';
export class Widget() {
constructor() {
getDataFromServer("dataForWidget")
.then(data => this.render(data));
}
render() {
...
}
}
Tôi đang tìm cách để kiểm tra Widget với một ví dụ giả getDataFromServer. Nếu tôi sử dụng các <script>s riêng biệt thay vì các mô-đun ES6, như trong Karma, tôi có thể viết bài kiểm tra của mình như sau:
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();
});
});
Tuy nhiên, nếu tôi đang kiểm tra các mô-đun ES6 riêng lẻ bên ngoài trình duyệt (như với Mocha + babel), tôi sẽ viết một cái gì đó như:
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();
});
});
Được rồi, nhưng bây giờ getDataFromServerkhông có sẵn window(tốt, hoàn toàn không có window) và tôi không biết cách tiêm trực tiếp vào widget.jsphạm vi của chính mình.
Vậy tôi phải đi đâu từ đây?
- Có cách nào để truy cập phạm vi
widget.jshoặc ít nhất là thay thế nhập khẩu của nó bằng mã của riêng tôi không? - Nếu không, làm thế nào tôi
Widgetcó thể kiểm tra?
Thứ tôi đã xem xét:
a. Hướng dẫn tiêm phụ thuộc.
Xóa tất cả nhập khẩu từ widget.jsvà mong đợi người gọi cung cấp deps.
export class Widget() {
constructor(deps) {
deps.getDataFromServer("dataForWidget")
.then(data => this.render(data));
}
}
Tôi rất khó chịu với việc làm rối giao diện công khai của Widget như thế này và tiết lộ chi tiết triển khai. Không đi.
b. Cho phép nhập khẩu để cho phép chế nhạo họ.
Cái gì đó như:
import { getDataFromServer } from 'network.js';
export let deps = {
getDataFromServer
};
export class Widget() {
constructor() {
deps.getDataFromServer("dataForWidget")
.then(data => this.render(data));
}
}
sau đó:
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();
});
});
Điều này ít xâm lấn hơn nhưng đòi hỏi tôi phải viết rất nhiều bản tóm tắt cho mỗi mô-đun, và vẫn có nguy cơ tôi sử dụng getDataFromServerthay vì deps.getDataFromServermọi lúc. Tôi không yên tâm về điều đó, nhưng đó là ý tưởng tốt nhất của tôi cho đến nay.
createSpy( github.com/jasmine/jasmine/blob/iêu ) với một tham chiếu được nhập vào getDataFromServer từ mô-đun 'network.js'. Vì vậy, trong tệp thử nghiệm của tiện ích bạn nhập getDataFromServer, và sau đó sẽlet spy = createSpy('getDataFromServer', getDataFromServer)
spyOntrên đối tượng đó, được nhập từ network.jsmô-đun. Nó luôn luôn là một tham chiếu đến cùng một đối tượng.
Widgetgiao diện công cộng? Widgetbị rối mà không có deps . Tại sao không làm cho sự phụ thuộc rõ ràng?