Skip to content

Commit 072e02b

Browse files
authoredJan 3, 2024
fix(spy): don't allow Promise in mockImplementation (#4859)
1 parent 1fee63f commit 072e02b

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed
 

‎packages/spy/src/index.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,15 @@ export interface MockInstance<TArgs extends any[] = any[], TReturns = any> {
154154
* const increment = vi.fn().mockImplementation(count => count + 1);
155155
* expect(increment(3)).toBe(4);
156156
*/
157-
mockImplementation(fn: ((...args: TArgs) => TReturns) | (() => Promise<TReturns>)): this
157+
mockImplementation(fn: ((...args: TArgs) => TReturns)): this
158158
/**
159159
* Accepts a function that will be used as a mock implementation during the next call. Can be chained so that multiple function calls produce different results.
160160
* @example
161161
* const fn = vi.fn(count => count).mockImplementationOnce(count => count + 1);
162162
* expect(fn(3)).toBe(4);
163163
* expect(fn(3)).toBe(3);
164164
*/
165-
mockImplementationOnce(fn: ((...args: TArgs) => TReturns) | (() => Promise<TReturns>)): this
165+
mockImplementationOnce(fn: ((...args: TArgs) => TReturns)): this
166166
/**
167167
* Overrides the original mock implementation temporarily while the callback is being executed.
168168
* @example
@@ -479,16 +479,16 @@ function enhanceSpy<TArgs extends any[], TReturns>(
479479
stub.mockReturnValueOnce = (val: TReturns) => stub.mockImplementationOnce(() => val)
480480

481481
stub.mockResolvedValue = (val: Awaited<TReturns>) =>
482-
stub.mockImplementation(() => Promise.resolve(val as TReturns))
482+
stub.mockImplementation(() => Promise.resolve(val as TReturns) as any)
483483

484484
stub.mockResolvedValueOnce = (val: Awaited<TReturns>) =>
485-
stub.mockImplementationOnce(() => Promise.resolve(val as TReturns))
485+
stub.mockImplementationOnce(() => Promise.resolve(val as TReturns) as any)
486486

487487
stub.mockRejectedValue = (val: unknown) =>
488-
stub.mockImplementation(() => Promise.reject(val))
488+
stub.mockImplementation(() => Promise.reject(val) as any)
489489

490490
stub.mockRejectedValueOnce = (val: unknown) =>
491-
stub.mockImplementationOnce(() => Promise.reject(val))
491+
stub.mockImplementationOnce(() => Promise.reject(val) as any)
492492

493493
Object.defineProperty(stub, 'mock', {
494494
get: () => mockContext,

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

+21
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,27 @@ describe('jest mock compat layer', () => {
5252
expect(mock2.getMockImplementation()).toBeUndefined()
5353
})
5454

55+
it('implementation types allow only function returned types', () => {
56+
function fn() {
57+
return 1
58+
}
59+
60+
function asyncFn() {
61+
return Promise.resolve(1)
62+
}
63+
64+
const mock1 = vi.fn(fn)
65+
const mock2 = vi.fn(asyncFn)
66+
67+
mock1.mockImplementation(() => 2)
68+
// @ts-expect-error promise is not allowed
69+
mock1.mockImplementation(() => Promise.resolve(2))
70+
71+
// @ts-expect-error non-promise is not allowed
72+
mock2.mockImplementation(() => 2)
73+
mock2.mockImplementation(() => Promise.resolve(2))
74+
})
75+
5576
it('implementation sync fn', () => {
5677
const originalFn = function () {
5778
return 'original'

0 commit comments

Comments
 (0)
Please sign in to comment.