模拟窗口对象会导致错误无法在 Window.get 历史记录中读取 null 属性(读取“_history”)[作为历史记录]

问题描述 投票:0回答:1

我有一个 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]
javascript vue.js jsdom vitest
1个回答
0
投票

正是

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
更方便,因为它不需要清理。

© www.soinside.com 2019 - 2024. All rights reserved.