Skip to content

Commit 3912554

Browse files
authored
fix: allow getMockImplementation to return "once" implementation (#7033)
1 parent ac9ba15 commit 3912554

File tree

2 files changed

+25
-5
lines changed

2 files changed

+25
-5
lines changed

packages/spy/src/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -215,12 +215,11 @@ export interface MockInstance<T extends Procedure = Procedure> {
215215
*/
216216
mockRestore(): void
217217
/**
218-
* Performs the same actions as `mockReset` and restores the inner implementation to the original function.
218+
* Returns current permanent mock implementation if there is one.
219219
*
220-
* Note that restoring a mock created with `vi.fn()` will set the implementation to an empty function that returns `undefined`. Restoring a mock created with `vi.fn(impl)` will restore the implementation to `impl`.
220+
* If mock was created with `vi.fn`, it will consider passed down method as a mock implementation.
221221
*
222-
* To automatically call this method before each test, enable the [`restoreMocks`](https://vitest.dev/config/#restoremocks) setting in the configuration.
223-
* @see https://vitest.dev/api/mock#getmockimplementation
222+
* If mock was created with `vi.spyOn`, it will return `undefined` unless a custom implementation was provided.
224223
*/
225224
getMockImplementation(): NormalizedPrecedure<T> | undefined
226225
/**
@@ -575,7 +574,8 @@ function enhanceSpy<T extends Procedure>(
575574
return stub
576575
}
577576

578-
stub.getMockImplementation = () => implementation
577+
stub.getMockImplementation = () =>
578+
implementationChangedTemporarily ? implementation : (onceImplementations.at(0) || implementation)
579579
stub.mockImplementation = (fn: T) => {
580580
implementation = fn
581581
state.willCall(mockCall)

test/core/test/jest-mock.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,4 +518,24 @@ describe('jest mock compat layer', () => {
518518
vi.mocked(dogMax.speak).mockReturnValue('woof woof')
519519
expect(dogMax.speak()).toBe('woof woof')
520520
})
521+
522+
it('returns temporary implementations from getMockImplementation()', () => {
523+
const fn = vi.fn()
524+
525+
const temporaryMockImplementation = () => 'mocked value'
526+
fn.mockImplementationOnce(temporaryMockImplementation)
527+
expect(fn.getMockImplementation()).toBe(temporaryMockImplementation)
528+
529+
// After calling it, it should be back to undefined
530+
fn()
531+
expect(fn.getMockImplementation()).toBe(undefined)
532+
533+
const mockImplementation = () => 'other mocked value'
534+
fn.mockImplementation(mockImplementation)
535+
expect(fn.getMockImplementation()).toBe(mockImplementation)
536+
537+
// It should also overwrite permanent implementations
538+
fn.mockImplementationOnce(temporaryMockImplementation)
539+
expect(fn.getMockImplementation()).toBe(temporaryMockImplementation)
540+
})
521541
})

0 commit comments

Comments
 (0)