From 1f72543b190456e2c20a66512b00d0dee9a1cc27 Mon Sep 17 00:00:00 2001 From: Jeremy Klas Date: Tue, 9 Aug 2022 22:06:28 -0700 Subject: [PATCH 1/2] handle undefined returns of module mocks, and update migration docs --- docs/guide/migration.md | 13 +++++++++++++ examples/mocks/test/factory.test.ts | 2 ++ packages/vitest/src/runtime/mocker.ts | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/guide/migration.md b/docs/guide/migration.md index d10de506ce3c..0d2b887af4bb 100644 --- a/docs/guide/migration.md +++ b/docs/guide/migration.md @@ -14,6 +14,19 @@ Jest has their [globals API](https://jestjs.io/docs/api) enabled by default. Vit If you decide to keep globals disabled, be aware that common libraries like [`testing-library`](https://testing-library.com/) will not run auto DOM [cleanup](https://testing-library.com/docs/svelte-testing-library/api/#cleanup). +**Module mocks** + +When mocking a module in Jest, if the factory argument returned a primitive, the mock would implicitly mock the default export. In Vitest, the factory argument has to return an object where each export is explicitly defined. For example, the following `jest.mock` would have to be updated as follows: + +```diff +- jest.mock('./some-path', () => 'hello') ++ vi.mock('./some-path', () => ({ ++ default: 'hello'; ++ }) +``` + +For more details please refer to the [vi.mock api](/api/#vi-mock) + **Auto-Mocking Behaviour** Unlike Jest, mocked modules in `/__mocks__` are not loaded unless `vi.mock()` is called. If you need them to be mocked in every test, like in Jest, you can mock them inside [`setupFiles`](/config/#setupfiles). diff --git a/examples/mocks/test/factory.test.ts b/examples/mocks/test/factory.test.ts index 0cf1822ebf0a..1567d88efe10 100644 --- a/examples/mocks/test/factory.test.ts +++ b/examples/mocks/test/factory.test.ts @@ -7,6 +7,7 @@ vi .mock('../src/example', () => ({ mocked: true, then: 'a then export', + ok: undefined, square: (a: any, b: any) => a + b, asyncSquare: async (a: any, b: any) => Promise.resolve(a + b), })) @@ -60,6 +61,7 @@ describe('mocking with factory', () => { }) test('defined exports on mock', async () => { + expect((example as any).ok).toBe(undefined) expect((example as any).then).toBe('a then export') expect((example as any).mocked).toBe(true) expect(example.square(2, 3)).toBe(5) diff --git a/packages/vitest/src/runtime/mocker.ts b/packages/vitest/src/runtime/mocker.ts index 7361cbff8741..d2105de179c3 100644 --- a/packages/vitest/src/runtime/mocker.ts +++ b/packages/vitest/src/runtime/mocker.ts @@ -122,7 +122,7 @@ export class VitestMocker { if (target instanceof Promise) return target.then.bind(target) } - else if (val === undefined) { + else if (!(prop in target)) { throw new Error(`[vitest] No "${prop}" export is defined on the "${dep}"`) } From c05e18ad86088652f241edc30bcad60a321a3e09 Mon Sep 17 00:00:00 2001 From: Jeremy Klas Date: Tue, 9 Aug 2022 22:44:00 -0700 Subject: [PATCH 2/2] correct docs --- docs/guide/migration.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/migration.md b/docs/guide/migration.md index 0d2b887af4bb..17d52b49c4fb 100644 --- a/docs/guide/migration.md +++ b/docs/guide/migration.md @@ -16,12 +16,12 @@ If you decide to keep globals disabled, be aware that common libraries like [`te **Module mocks** -When mocking a module in Jest, if the factory argument returned a primitive, the mock would implicitly mock the default export. In Vitest, the factory argument has to return an object where each export is explicitly defined. For example, the following `jest.mock` would have to be updated as follows: +When mocking a module in Jest, the factory argument's return value is the default export. In Vitest, the factory argument has to return an object with each export explicitly defined. For example, the following `jest.mock` would have to be updated as follows: ```diff - jest.mock('./some-path', () => 'hello') + vi.mock('./some-path', () => ({ -+ default: 'hello'; ++ default: 'hello', + }) ```