diff --git a/packages/spy/src/index.ts b/packages/spy/src/index.ts index b83d2c9a0f63..6a57cf60a357 100644 --- a/packages/spy/src/index.ts +++ b/packages/spy/src/index.ts @@ -154,10 +154,10 @@ export function spyOn>>( methodName: G, accessType: 'set', ): SpyInstance<[T[G]], void> -export function spyOn> | Classes>)>( +export function spyOn> | Methods>)>( obj: T, methodName: M, -): Required[M] extends (...args: infer A) => infer R | (new (...args: infer A) => infer R) ? SpyInstance : never +): Required[M] extends ({ new (...args: infer A): infer R }) | ((...args: infer A) => infer R) ? SpyInstance : never export function spyOn( obj: T, method: K, diff --git a/test/core/test/fixtures/hello-mock.ts b/test/core/test/fixtures/hello-mock.ts new file mode 100644 index 000000000000..805866f4b568 --- /dev/null +++ b/test/core/test/fixtures/hello-mock.ts @@ -0,0 +1,5 @@ +export class HelloWorld { + hello() { + return 'Hello World!' + } +} diff --git a/test/core/test/spy.test.ts b/test/core/test/spy.test.ts index 140cbd1eef77..35cddb90374a 100644 --- a/test/core/test/spy.test.ts +++ b/test/core/test/spy.test.ts @@ -1,12 +1,32 @@ import { describe, expect, test, vi } from 'vitest' +import * as mock from './fixtures/hello-mock' /** * @vitest-environment happy-dom */ describe('spyOn', () => { + const hw = new mock.HelloWorld() + test('correctly infers method types', async () => { vi.spyOn(localStorage, 'getItem').mockReturnValue('world') expect(window.localStorage.getItem('hello')).toEqual('world') }) + + test('infers a class correctly', () => { + vi.spyOn(mock, 'HelloWorld').mockImplementationOnce(() => { + const Mock = vi.fn() + Mock.prototype.hello = vi.fn(() => 'hello world') + return new Mock() + }) + + const mockedHelloWorld = new mock.HelloWorld() + expect(mockedHelloWorld.hello()).toEqual('hello world') + }) + + test('infers a method correctly', () => { + vi.spyOn(hw, 'hello').mockImplementationOnce(() => 'hello world') + + expect(hw.hello()).toEqual('hello world') + }) })