Created
December 4, 2024 16:19
-
-
Save marcogrcr/08d1b10861992d1c26bf43288341b843 to your computer and use it in GitHub Desktop.
Vitest mocking basics
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
afterEach, | |
beforeEach, | |
expect, | |
it, | |
MockedClass, | |
MockedFunction, | |
vi, | |
} from "vitest"; | |
// import module to mock | |
import { MyClass, myFunction, myObject } from "./my-module"; | |
// mock the module | |
vi.mock("./my-module"); | |
// create type-safe mocked versions of classes, functions and objects | |
const MyClassMock = MyClass as MockedClass<typeof MyClass>; | |
const myFunctionMock = myFunction as MockedFunction<typeof myFunction>; | |
const myObjectMock = vi.mocked(myObject); | |
// if an instance of a mocked class needs to be created in test code | |
let myClassInstance: MyClass; | |
beforeEach(async () => { | |
myClassInstance = new MyClass( | |
...([] as unknown as ConstructorParameters<typeof MyClass>), | |
); | |
}); | |
// mocked fields must be restored manually | |
const myFieldBackup = myObject.myField; | |
afterEach(() => { | |
// @ts-expect-error Field is not optional | |
delete MyClassMock.prototype.myField; | |
myObject.myField = myFieldBackup; | |
}); | |
it("mocks function", () => { | |
myFunctionMock.mockReturnValue("value"); | |
expect(myFunction()).toBe("value"); | |
}); | |
it("mocks class", () => { | |
// field | |
expect(MyClassMock.prototype).not.toHaveProperty("myField"); | |
MyClassMock.prototype.myField = "value"; | |
expect(myClassInstance.myField).toBe("value"); | |
// property | |
vi.spyOn(MyClassMock.prototype, "myProp", "get").mockReturnValue("value"); | |
expect(myClassInstance.myProp).toBe("value"); | |
// method | |
MyClassMock.prototype.myMethod.mockReturnValue("value"); | |
expect(myClassInstance.myMethod()).toBe("value"); | |
}); | |
it("mocks object", async () => { | |
// field | |
expect(myObject).toHaveProperty("myField"); | |
myObject.myField = "value"; | |
expect(myObject.myField).toBe("value"); | |
// property | |
vi.spyOn(myObject, "myProp", "get").mockReturnValue("value"); | |
expect(myObject.myProp).toBe("value"); | |
// method | |
myObjectMock.myMethod.mockReturnValue("value"); | |
expect(myObject.myMethod()).toBe("value"); | |
// async method | |
myObjectMock.myAsyncMethod.mockResolvedValue("value"); | |
await expect(myObject.myAsyncMethod()).resolves.toBe("value"); | |
}); | |
it("mocks object with original implementations", async () => { | |
const { myObject: actualMyObject } = | |
await vi.importActual<typeof import("./my-module")>("./my-module"); | |
// property | |
vi.spyOn(myObject, "myProp", "get").mockImplementation( | |
() => actualMyObject.myProp, | |
); | |
expect(myObject.myProp).toBe("not implemented"); | |
// method | |
myObjectMock.myMethod.mockImplementation( | |
actualMyObject.myMethod.bind(actualMyObject), | |
); | |
expect(myObject.myMethod()).toBe("not implemented"); | |
// async method | |
myObjectMock.myAsyncMethod.mockImplementation( | |
actualMyObject.myAsyncMethod.bind(actualMyObject), | |
); | |
await expect(myObject.myAsyncMethod()).resolves.toBe("not implemented"); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export interface MyClassOptions {} | |
export function myFunction(): string { | |
throw new Error("not implemented"); | |
} | |
export class MyClass { | |
myField: string = "not implemented"; | |
constructor(options: MyClassOptions) {} | |
get myProp(): string { | |
return "not implemented"; | |
} | |
myMethod(): string { | |
return "not implemented"; | |
} | |
async myAsyncMethod(): Promise<string> { | |
return "not implemented"; | |
} | |
} | |
export const myObject = { | |
myField: "not implemented", | |
get myProp(): string { | |
return "not implemented"; | |
}, | |
myMethod(): string { | |
return "not implemented"; | |
}, | |
async myAsyncMethod(): Promise<string> { | |
return "not implemented"; | |
}, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment