diff --git a/docs/api/mock.md b/docs/api/mock.md index 9579cc03f..025641b7e 100644 --- a/docs/api/mock.md +++ b/docs/api/mock.md @@ -52,6 +52,21 @@ function mockClear(): MockInstance Clears all information about every call. After calling it, all properties on `.mock` will return to their initial state. This method does not reset implementations. It is useful for cleaning up mocks between different assertions. +```ts +const person = { + greet: (name: string) => `Hello ${name}`, +} +const spy = vi.spyOn(person, 'greet').mockImplementation(() => 'mocked') +expect(person.greet('Alice')).toBe('mocked') +expect(spy.mock.calls).toEqual([['Alice']]) + +// clear call history but keep mock implementation +spy.mockClear() +expect(spy.mock.calls).toEqual([]) +expect(person.greet('Bob')).toBe('mocked') +expect(spy.mock.calls).toEqual([['Bob']]) +``` + To automatically call this method before each test, enable the [`clearMocks`](/config/#clearmocks) setting in the configuration. ## mockName @@ -197,7 +212,7 @@ await asyncMock() // throws Error<'Async error'> function mockReset(): MockInstance ``` -Does what `mockClear` does and resets inner implementation to the original function. +Does what [`mockClear`](#mockClear) does and resets inner implementation to the original function. This also resets all "once" implementations. Note that resetting a mock from `vi.fn()` will set implementation to an empty function that returns `undefined`. @@ -205,6 +220,22 @@ resetting a mock from `vi.fn(impl)` will restore implementation to `impl`. This is useful when you want to reset a mock to its original state. +```ts +const person = { + greet: (name: string) => `Hello ${name}`, +} +const spy = vi.spyOn(person, 'greet').mockImplementation(() => 'mocked') +expect(person.greet('Alice')).toBe('mocked') +expect(spy.mock.calls).toEqual([['Alice']]) + +// clear call history and reset implementation, but method is still spied +spy.mockReset() +expect(spy.mock.calls).toEqual([]) +expect(person.greet).toBe(spy) +expect(person.greet('Bob')).toBe('Hello Bob') +expect(spy.mock.calls).toEqual([['Bob']]) +``` + To automatically call this method before each test, enable the [`mockReset`](/config/#mockreset) setting in the configuration. ## mockRestore @@ -213,11 +244,27 @@ To automatically call this method before each test, enable the [`mockReset`](/co function mockRestore(): MockInstance ``` -Does what `mockReset` does and restores original descriptors of spied-on objects. +Does what [`mockReset`](#mockReset) does and restores original descriptors of spied-on objects. Note that restoring a mock from `vi.fn()` will set implementation to an empty function that returns `undefined`. Restoring a mock from `vi.fn(impl)` will restore implementation to `impl`. +```ts +const person = { + greet: (name: string) => `Hello ${name}`, +} +const spy = vi.spyOn(person, 'greet').mockImplementation(() => 'mocked') +expect(person.greet('Alice')).toBe('mocked') +expect(spy.mock.calls).toEqual([['Alice']]) + +// clear call history and restore spied object method +spy.mockRestore() +expect(spy.mock.calls).toEqual([]) +expect(person.greet).not.toBe(spy) +expect(person.greet('Bob')).toBe('Hello Bob') +expect(spy.mock.calls).toEqual([]) +``` + To automatically call this method before each test, enable the [`restoreMocks`](/config/#restoremocks) setting in the configuration. ## mockResolvedValue diff --git a/test/core/test/jest-mock.test.ts b/test/core/test/jest-mock.test.ts index 17dbcd2ec..9276335e4 100644 --- a/test/core/test/jest-mock.test.ts +++ b/test/core/test/jest-mock.test.ts @@ -559,4 +559,53 @@ describe('jest mock compat layer', () => { fn.mockImplementationOnce(temporaryMockImplementation) expect(fn.getMockImplementation()).toBe(temporaryMockImplementation) }) + + describe('docs example', () => { + it('mockClear', () => { + const person = { + greet: (name: string) => `Hello ${name}`, + } + const spy = vi.spyOn(person, 'greet').mockImplementation(() => 'mocked') + expect(person.greet('Alice')).toBe('mocked') + expect(spy.mock.calls).toEqual([['Alice']]) + + // clear call history but keep mock implementation + spy.mockClear() + expect(spy.mock.calls).toEqual([]) + expect(person.greet('Bob')).toBe('mocked') + expect(spy.mock.calls).toEqual([['Bob']]) + }) + + it('mockReset', () => { + const person = { + greet: (name: string) => `Hello ${name}`, + } + const spy = vi.spyOn(person, 'greet').mockImplementation(() => 'mocked') + expect(person.greet('Alice')).toBe('mocked') + expect(spy.mock.calls).toEqual([['Alice']]) + + // clear call history and reset implementation, but method is still spied + spy.mockReset() + expect(spy.mock.calls).toEqual([]) + expect(person.greet).toBe(spy) + expect(person.greet('Bob')).toBe('Hello Bob') + expect(spy.mock.calls).toEqual([['Bob']]) + }) + + it('mockRestore', () => { + const person = { + greet: (name: string) => `Hello ${name}`, + } + const spy = vi.spyOn(person, 'greet').mockImplementation(() => 'mocked') + expect(person.greet('Alice')).toBe('mocked') + expect(spy.mock.calls).toEqual([['Alice']]) + + // clear call history and restore spied object method + spy.mockRestore() + expect(spy.mock.calls).toEqual([]) + expect(person.greet).not.toBe(spy) + expect(person.greet('Bob')).toBe('Hello Bob') + expect(spy.mock.calls).toEqual([]) + }) + }) })