Mock window.assign.location and window.open in browser mode #10622
-
|
Hi vitest community! In our system, we have lots of We migrated to latest Hopefully not too many people have to write tests like us. We have a found a few workarounds, but nothing feels truly "vitest". Happy testing :) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
In Browser Mode I would treat For The most Vitest-friendly pattern is to put navigation behind your own module boundary and mock/spy that module instead: // navigation.ts
export function assign(url: string | URL) {
window.location.assign(url)
}
export function open(url: string | URL, target = "_blank", features?: string) {
return window.open(url, target, features)
}Then in Browser Mode: import * as navigation from "./navigation"
vi.mock(import("./navigation"), { spy: true })
vi.mocked(navigation.assign).mockImplementation(() => {})
vi.mocked(navigation.open).mockImplementation(() => null)That lines up with the Browser Mode limitation documented for module exports: native ESM namespace objects/browser globals cannot always be reconfigured like they can in Node/jsdom, so Vitest supports For tests where you want real navigation semantics, I would move those to Playwright/Cypress-style e2e and assert the URL/popup behavior there. For component/unit tests, the wrapper module is the least surprising long-term approach. |
Beta Was this translation helpful? Give feedback.
In Browser Mode I would treat
window.location.assignas effectively not mockable in the oldhappy-domstyle. Browser Mode is running in a real browser, soLocationbehaves like the platform object it is;vi.spyOn(location, "assign")working in DOM simulators was the less-realistic part.For
window.open, you may be able to stub/spy depending on the browser/property descriptor, but I would not build a test strategy around patching browser navigation globals.The most Vitest-friendly pattern is to put navigation behind your own module boundary and mock/spy that module instead: