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ờ getDataFromServer
khô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.js
phạ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.js
hoặ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
Widget
có 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.js
và 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 getDataFromServer
thay vì deps.getDataFromServer
mọ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)
spyOn
trên đối tượng đó, được nhập từ network.js
mô-đun. Nó luôn luôn là một tham chiếu đến cùng một đối tượng.
Widget
giao diện công cộng? Widget
bị rối mà không có deps
. Tại sao không làm cho sự phụ thuộc rõ ràng?