Cross posted on my website mitchinson.dev
TL;DR
GetANumber.test.ts mocks a class, and further customizes a class method on that mocked class for a single test.
Purpose
It was surprisingly hard to find a recently written article about the fastest way to setup Jest with some simple class mocks in Typescript. The following example demonstrates mocking a class and modifying methods of that mocked class within a single test.
Libraries like jest-ts-auto-mock are not used, cause I was unable to find a way to get them to work. Could have just been using them wrong but who knows.
I used the following methods to mock classes in an Express app while coding in test driven development.
Explanation
Comments are all over in this Example Repo, but some highlights are:
-
jest.mock
ends up at the top of the file when it's transpiled.- Even if you put it under other things, it gets pulled to the top.
///////////////////
jest.mock("./Class", mockOne);
it("does a thing", () => {
expect(class).toBe(one)
})
it("does another thing", () => {
jest.mock("./Class", mockTwo);
expect(class).toBe(two)
})
///////////////////
// is really
///////////////////
jest.mock("./Class", mockOne); // this mock is useless
jest.mock("./Class", mockTwo); // as it's immediately replaced
it("does a thing", () => {
expect(class).toBe(one)
})
it("does another thing", () => {
expect(class).toBe(two)
})
///////////////////
// You might as well always write `.mock` calls at the top of your file.
- The example mocks a class that's a default export. Named exports can also be mocked by nesting the class mockImplementation one layer deeper.
-
jest.mock('{path_to_custom_class}')
will replace that paths default export in the runtime with the defined mock in__mocks__
dir defined at the same level. - If you'd like to modify a mock / assert things that happened to a mock, you need to import them from the "real" class.
- Never manually import from
__mocks__
, get the exports of__mocks__
"through" a normal import.
- Never manually import from
import * as MockNumberGen from "./__mocks__/NumberGen";
import * as NumberGen from "./NumberGen"; // __mocks__/CVEPathData
// Give me the mock class i've defined in __mocks__/{classname} and let me
// name it mock{ClassName}Constructor
// Give me the mock function i've defined in __mocks__/{classname}
const { default: mockNumberGenConstructor, mockGetOne } =
// Get these things from the NumberGen class, because I know that jest
// has secretly replaced it with the contents of MockNumberGen
NumberGen as unknown as typeof MockNumberGen;
// Tell typescript that these things are really coming from MockNumberGen,
// so it should type them as such
The full test is available here
Top comments (0)