我有一个 Vue 组件,其方法如下,我正在尝试对其进行单元测试:
const close = () => {
(window.open('', '_self').opener=window).close()
}
我的测试如下:
import { createRouter, createWebHistory } = from "vue-router";
describe('test suite', async () => {
let router
let wrapper
beforeEach(async () => {
router = createRouter({
history: createWebHistory(),
routes: routes
})
wrapper = mount(MyComponent, {
global: {
plugins: [router]
}
})
})
test('window.close is called when btn is clicked', async () => {
const windowSpy = vi.spyOn(window, 'open').mockReturnValue({
close: vi.fn()
})
const btn = wrapper.find('[name="BTN_1"]')
await btn.trigger('click')
expect(windowSpy).toHaveBeenCalledOnce()
})
})
测试成功,但在控制台中输出错误消息:
[Vue Router warn]: Unexpected error when starting the router: TypeError: Cannot read properites of null (reading '_history') at Window.get history [as history]
正是
jsdom
为Vitest中的Node环境提供了window
。
问题是这段代码有一个由简写语法引起的错误:
(window.open('', '_self').opener=window).close()
close
是在 window
上调用的,而不是由 open
返回的窗口对象(在这种情况下,在浏览器中无论如何都是 window
)。
如此处所解释,
不支持关闭 jsdom 后在 jsdom 上运行代码,因此这是按预期工作的。
为了与现有代码一起使用,应将其修改为:
const w = window.open('', '_self');
w.opener = window;
w.close();
或者测试应该改为:
const windowOpenSpy = vi.spyOn(window, 'open').mockReturnValue({});
const windowCloseSpy = vi.spyOn(window, 'close').mockReturnValue(undefined);
此外,在测试中使用
createMemoryHistory
更方便,因为它不需要清理。