Jest for a Typescript-based React app
I recently had to install and configure Jest in a React app written using Typescript and ran into quite a few roadblocks. So, I thought of detailing the steps I followed to overcome the difficulties.
I used Jest as the test runner, and React Testing Library to test the React components.
Installing the dependencies
First, let’s install the needed dependencies.
npm install --save-dev @testing-library/jest-dom @testing-library/react @types/jest jest ts-jest
Here, @testing-library/jest-dom
is used to extend the Jest matchers and ts-jest
is used to help Jest test Typescript files. @types/jest
provides the type definitions for the Jest library.
Configuring Jest
Once installed, then we need to configure Jest. We can do this by creating a key called jest
in the package.json
file and passing the configurational details into it as a value object.
“jest”:{}
Transforming Typescript files
First, let’s configure Jest to transform all the Typescript files using the ts-jest
transformer. Create a key called transform
and then pass the file pattern to be transformed and the transformer you want to use as a child key-value pair. Here, both tsx
files and ts
files will be transformed using the ts-jest
transformer.
"jest": { "transform": { "^.+\\.tsx$": "ts-jest", "^.+\\.ts$": "ts-jest" } }
Declaring global constants
If there are global constants you are using in your project—such as the ones you created using the Webpack DefinePlugin—then you can declare them in the configuration so that Jest can understand the constants in your code. You can use the child key called globals
to that end.
"jest": { "globals": { "APP_NAME": "Demo" }, "transform": { "^.+\\.tsx$": "ts-jest", "^.+\\.ts$": "ts-jest" }, }
Mocking files
Next, we need to mock the static files and stylesheets used in our app. To mock these, first, we need to create two mock files. I created a directory called mocks and created two mock files called file_mock.js
and style_mock.js
. which export dummy values using the CommonJS module format. This is the content of the mock files.
module.exports = "";
After completing the above steps, we need to tell Jest to mock files using our mock files. To do that, we need to use the moduleNameMapper
key. Pass the regex file pattern to match the files you want to mock as the key and the path to the mock files as the value. You can use <rootDir>
to refer to the root of your project directory.
"jest": { "globals": { "APP_NAME": "Demo" }, "transform": { "^.+\\.tsx$": "ts-jest", "^.+\\.ts$": "ts-jest" }, "moduleNameMapper": { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/mocks/file_mock.js", "\\.(css|less)$": "<rootDir>/src/mocks/style_mock.js" } }
Extending expect of Jest
This configuration should work fine. But when using the React Testing Library, we may have to use additional matchers such as toBeInTheDocument()
which are not provided by Jest by default. So, we need to use the extend-expect
module provided by @testing-library/jest-dom
.
However, whenever we need to use these additional matchers, we need to import the extend-expect
module into each and every test file, and this can be really inconvenient.
To solve this issue, we can have Jest import this module once and have it available across all our test files. To do this, first, let’s create a file called setup_test.js
. Let’s import the extend-expect
module into it.
import "@testing-library/jest-dom/extend-expect";
Now, we need to tell Jest to load it before each test. We can do so by passing the path of the setup_test.js
file into the setupFilesAfterEnv array in the jest configuration. Again, <rootDir>
can be used to refer to the root of the project. So, your final configuration would like this:
"jest": { "globals": { "APP_NAME": "Demo" }, "transform": { "^.+\\.tsx$": "ts-jest", "^.+\\.ts$": "ts-jest" }, "moduleNameMapper": { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/mocks/file_mock.js", "\\.(css|less)$": "<rootDir>/src/mocks/style_mock.js" }, "setupFilesAfterEnv": [ "<rootDir>/src/setup_test.ts" ] },
That’s it, you are good to start writing tests for your app. You can find the sample repo here.
Leave a Reply