DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Darragh O'Riordan
Darragh O'Riordan

Posted on • Originally published at darraghoriordan.com on

5 Jest and Typescript tips

I’ve been working with jest every day for the past month or so. I had to learn a few tricks as I went. I was mocking, using async, upgrading versions and working in vscode. Here are five things I learned.

Creating typed jest mocks

Jest has a decent mocking system but the creation and typing can be made a bit easier by using a helper library. I have used jest-create-mock-instance for the past couple of months and it works really well.

# You should install the library in your project
yarn add -D jest-create-mocked-instance
Enter fullscreen mode Exit fullscreen mode

Then in your test where you need to mock a dependency you just need to

import createMockInstance from 'jest-create-mock-instance'

let mockedDependency: MyDependencyClass

mockedDependency = createMockInstance(MyDependencyClass)

let classUnderTest: MyClassToTest

classUnderTest = new MyClassToTest(mockedDependency)
Enter fullscreen mode Exit fullscreen mode

Typing a typescript array for jest test-each cases

I wanted to create a truth table in another file to pass into jest’s test.each() helper.

The typing for this method is an array of sub arrays with the specific parameters defined. The way to define this in TS is

export const getTruthTable = (): Array<
    [
        MyEnumType1,
        MyEnumType2,
        string,
        boolean
    ]
> => {
    return [
        [
            MyEnumType1.YES,
            MyEnumType2.PRIMARY,
            "string test value1",
            false,
        ],
        [
            MyEnumType1.NO,
            MyEnumType2.SECONDARY,
            "string test value2",
            true,
        ],

        // and then use this in jest with

 test.each(getTruthTable())(
        "is applicable as expected",
        (
            val1: MyEnumType1,
            val1: MyEnumType2,
            val1: string,
            expected: boolean
        ) => {
          // test the case here
          expect(result).toEqual(expected)
        }
Enter fullscreen mode Exit fullscreen mode

jest catch rejection

Jest has some specific methods for helping to test promises and async code

You can mock them using these helpers

jest
  .spyOn(myJestMock, 'myAsyncMethodIWantToResolveWithValue')
  .mockResolvedValue(new ThingToResolveWith())

jest
  .spyOn(myJestMock, 'myAsyncMethodIWantToReject')
  .mockRejectedValue(new ErrorToRejectWith())
Enter fullscreen mode Exit fullscreen mode

You can expect a specific resolution or rejection using

await expect(result).resolves.toEqual(expectedResponse)

await expect(result).rejects.toThrowError(MyCustomError)
Enter fullscreen mode Exit fullscreen mode

Upgrading to the latest ts-jest preset

If you had this setup in your jest.config.js file

    transform: {
        "^.+\\.(t|j)sx?$": "ts-jest",
    }
Enter fullscreen mode Exit fullscreen mode

You can just change it to this now (unless you had a custom setup where you have typescript files that you don’t want ts-jest to inspect).

    preset: "ts-jest",
Enter fullscreen mode Exit fullscreen mode

The preset is awesome and will find all your ts and tsx files.

Adding a snippet

To bring all this together in vscode I like to add a jest test snippet to avoid typing some of the boilerplate each time.

You can easily add snippets to your project by placing a file with the extension .code-snippets in your .vscode folder. The .vscode folder is in the root of your project. You can just add it if it’s not already there.

The snippet syntax is json. It’s a bit annoying to setup because each line is a string.

The prefix parameter is the name you would type in vscode and then hit tab to print the snippet to your file. Usually the first couple of letters are enough. ne..<TAB> then enter the name of the class under test.

    "Simple Test": {
        "scope": "typescript",
        "prefix": "newtest",
        "body": [
            "import createMockInstance from \"jest-create-mock-instance\";",
            "",
            "describe(\"$1\", () => {",
            " let classUnderTest: $1;",
            "",
            " let myMockedDep: jest.Mocked<MockClass>;",
            "",
            " beforeEach(() => {",
            " jest.resetAllMocks();",
            "",
            " myMockedDep = createMockInstance(MyDependency)",
            " classUnderTest = new $1(myMockedDep);",
            " });",
            "",
            " test.each([",
            " [\"true\", true],",
            " [\"false\", false],",
            " ])(\"is an expected response\", (input: string, expected: boolean) => {",
            " const result = classUnderTest.methodToTest(input);",
            " expect(result).toEqual(expected);",
            " });",
            "});"
        ],
        "description": "A simple test template for starting a unit test"
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

🌱 DEV runs on 100% open source code known as Forem.

Β 
Contribute to the codebase or learn how to host your own.