How to use TypeScript and Jest mocks
2019-07-10 — 1 Min Read — In Jest, TypeScript
It's pretty common to mock modules in Jest. When using TypeScript that might be a bit harder because they are not automatically resolved by TypeScript.
Let's say we are using a function useFooContext
from a module called foo
:
1// foo.d.ts2declare module "foo" {3 interface FooContext {4 bar: number;5 }67 export function useFooContext(): FooContext;8}
So we create a mock of the module foo
in the __mocks__
folder:
1// __mocks__/foo.ts2export const useFooContext = jest.fn(() => {});
And finally, create our test file using mocked foo
:
1// index.test.ts2import { useFooContext } from "foo";34test("sample test", () => {5 // Error: Property 'mockImplementation' does not exist on type '() => FooContext'.ts(2339)6 useFooContext.mockImplementation(() => {7 bar: 123;8 });910 const context = useFooContext();1112 expect(context.bar).toBe(123);13});
Property 'mockImplementation' does not exist on type '() => FooContext'.ts(2339)
TypeScript throws an error since it doesn't resolve mock files as Jest does. It expects useFooContext
to have the type defined in its definition.
Solution
We should hint TypeScript that the function imported is in fact a jest mock function.
1import {2 useFooContext,3 FooContext // Get the type returned by `useFooContext`4} from "foo";56// Create a new variable and type it as jest.Mock passing the type7const mockedUseFooContext = useFooContext as jest.Mock<FooContext>;89test("sample test", () => {10 // TypeScript will type check the value returned by the mock implementation 💯11 mockedUseFooContext.mockImplementation(() => {12 bar: "mocked return for this test";13 });1415 const context = mockedUseFooContext();1617 expect(context.bar).toBe(123);18});
I hope that's helpful!