Skip to content

Commit d6ceca9

Browse files
fix(spy): point ESM namespace spy error to module mocking docs (#10707)
Co-authored-by: Ryan Tang <24728770+ryandiginomad@users.noreply.github.com>
1 parent 0f86612 commit d6ceca9

3 files changed

Lines changed: 35 additions & 2 deletions

File tree

packages/spy/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ export function spyOn<T extends object, K extends keyof any>(
410410
|| error.message.includes('can\'t redefine non-configurable property'))
411411
) {
412412
throw new TypeError(
413-
`Cannot spy on export "${String(key)}". Module namespace is not configurable in ESM. See: https://vitest.dev/guide/browser/#limitations`,
413+
`Cannot spy on export "${String(key)}". Module namespace is not configurable in ESM. See: https://vitest.dev/guide/mocking/modules#mocking-a-module`,
414414
{ cause: error },
415415
)
416416
}

test/browser/test/mocking.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ it('spying on an esm module prints an error', () => {
1212
}
1313
})()
1414
expect(error.name).toBe('TypeError')
15-
expect(error.message).toMatchInlineSnapshot(`"Cannot spy on export "calculator". Module namespace is not configurable in ESM. See: https://vitest.dev/guide/browser/#limitations"`)
15+
expect(error.message).toMatchInlineSnapshot(`"Cannot spy on export "calculator". Module namespace is not configurable in ESM. See: https://vitest.dev/guide/mocking/modules#mocking-a-module"`)
1616

1717
expect(error.cause).toBeInstanceOf(TypeError)
1818
})

test/unit/test/mocking/vi-spyOn.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,39 @@ describe('vi.spyOn() edge cases', () => {
1919
expect(fn3.length).toBe(3)
2020
})
2121

22+
test('spying on a non-configurable ESM namespace export points to the module mocking docs, not browser mode', () => {
23+
// Fake an ES module namespace: `Symbol.toStringTag` is 'Module' and the
24+
// export is non-configurable, so `Object.defineProperty` throws
25+
// "Cannot redefine property" — the same guard the real ESM path hits.
26+
const namespace: Record<string, unknown> = {}
27+
Object.defineProperty(namespace, Symbol.toStringTag, { value: 'Module' })
28+
Object.defineProperty(namespace, 'answer', {
29+
value: () => 42,
30+
enumerable: true,
31+
configurable: false,
32+
writable: false,
33+
})
34+
Object.preventExtensions(namespace)
35+
36+
const error = (() => {
37+
try {
38+
vi.spyOn(namespace as any, 'answer')
39+
expect.unreachable()
40+
}
41+
catch (err) {
42+
return err as Error
43+
}
44+
})()
45+
46+
expect(error).toBeInstanceOf(TypeError)
47+
expect(error.message).toContain('Cannot spy on export "answer"')
48+
// This error fires in Node too, so it must not send users to the
49+
// browser-mode-only docs (issue #9467). It should point at the
50+
// environment-agnostic module mocking guide instead.
51+
expect(error.message).toContain('https://vitest.dev/guide/mocking/modules#mocking-a-module')
52+
expect(error.message).not.toContain('/guide/browser')
53+
})
54+
2255
test('can spy on a proxy with undefined descriptor\'s value', () => {
2356
const obj = new Proxy<{ fn: () => number }>({} as any, {
2457
get(_, prop) {

0 commit comments

Comments
 (0)
Sponsor
SponsoredKunjungi sekarang
Promo