我正在编写一个利用导入模块的实用程序,但我对如何正确模拟它有点困惑。
在实现中,我需要像这样调用导入模块周围的各种方法;
map = leaflet
.map('map')
.setView([38.58, -90.28], 15);
所以看来我需要两个级别的模拟:模拟
map
函数,然后模拟它返回的具有 setView
方法的对象。
在我的测试套件中,我有一个 beforeEach 生命周期钩子,它尝试模拟模块:
beforeEach(() => {
vi.mock("leaflet", () => { // Mock the import itself
// mocking the `Map` object returned from the `map()` function call
vi.mock("leaflet.Map", () => {
return {setView: vi.fn()}
})
// mocking the `map()` function and returning the mocked `Map` instance(?)
const mapMock = vi.fn()
.mockImplementation((id) => {
return new Map("")
})
// returning the object to replace the whole module import with
return {
default: {
map: () => mapMock,
}
}
})
})
但是当我在测试中使用它时:
it("can attach a map to the dom", () => {
const config = new MapConfiguration(
"map",
new GeographicCoordinates(38.0, -90.0),
15,
19
)
attachMap(config)
expect(leaflet.map).toHaveBeenCalled()
})
我收到一个奇怪的错误,我不确定它想告诉我什么
请记住,
vi.mock()
正在模拟整个模块,因此调用vi.mock("leaflet.Map")
实际上并不起作用。 vi.mock()
的path参数指的是正在导入的模块,因此要模拟“传单”模块,您需要vi.mock("leaflet")
,然后适当地模拟这些函数的返回值。此外,在另一个模拟内部调用它是行不通的。无论如何,它们都会被提升到文件的顶部,因此将其放入 beforeEach
中不会执行任何操作。
要模拟传单,在最基本的层面上,类似以下内容就可以了:
import leaflet from "leaflet";
import { expect, it, vi } from "vitest";
vi.mock("leaflet", () => {
return {
default: {
map: vi.fn().mockReturnValue({
setView: vi.fn(),
}),
},
};
});
it("can attach a map to the dom", () => {
const config = new MapConfiguration(
"map",
new GeographicCoordinates(38.0, -90.0),
15,
19,
);
attachMap(config);
expect(leaflet.map).toHaveBeenCalledWith("map");
});