Search code examples
vue.jsvitest

testing and mocking window.close spy not being called


I am using vitest with vue test utils for unit testing my vue component's methods. One of the test items is that a button should call a close() method on click, which in turn calls the browser window.close() method:

const close = () => {
  console.log('close() called')
  window.close()
}

I have a unit test that mocks window.close but the test is not passing: expected "spy" to be called once, but got 0 times

I am sure that the component's close() method was being called, as I am seeing the console.log output in the test logs.

Here is the test method:

import { test, vi, expect } from "vitest";
import { mount } from "@vue/test-utils";

test('window.close is called when button is clicked', async () => {
  const wrapper = mount(MyComponent, {
    global: {
      plugins: [router]
    }
  })
  const btn = wrapper.find('#exit-button')
  await btn.trigger('click')
  window.close = vi.fn()
  expect(window.close).toHaveBeenCalledOnce()
})

Solution

  • There may be no negative side effects in replacing window.close in fake DOM, but generally this is discouraged. spyOn is preferred with methods because it makes it possible to restore original implementation.

    A spy should be set before it is called, it should be:

      vi.spyOn(window, 'close')
      const btn = wrapper.find('#exit-button')
      await btn.trigger('click')
      expect(window.close).toHaveBeenCalledOnce()