How to Set up React Test with Mocha and Enzyme for TypeScript
- By : Mydatahack
- Category : Front-End, Web Technologies
- Tags: Enzyme, JSDOM, mocha, React, TypeScript
Enzyme is created by Airbnb for React component testing. You can easily test components’ output and it works with different testing frameworks like Mocha or Jest. This post focuses on setting up the test environment with Mocha for TypeScript.
If you are used to JavaScript and fairly new to TypeScript, setting up unit test can be cumbersome. Basically, TypeScript complains about almost everything that you used to do with JavaScript. However, once you get your head around it, it becomes easier. When I set this up first time, it took me a long time to figure out why TypeScript is complaining about things like window does not exist on type Global or mount method not working because a global document is not loaded. But, getting this work helped me to understand TypeScript a little bit better.
The complete example can be found on this repo.
Let’s get started.
(1) Install dependencies
With TypeScript, you need to install a regular module and @types module. Most of the common modules has @types available these days. So, you can simply install the regular module as well as the one prefixed with @types. Some modules are written in TypeScript and you don’t need to install @types. For example, a test coverage tool, istanbul is written in TypeScript and does not require any type module.
Using chai for assertion library. ts-node is also required to run TypeScript in the node environment. Later, you need to register ts-node in the mocha command.
npm i chai mocha ts-node --save-dev npm i @types/chai @types/mocha @types/sinon --save-dev
Now, let’s install dependencies for Enzyme. Mocha doesn’t run tests in a Node environment, not in a browser environment. Therefore, enzyme’s mount API requires a DOM. To simulate a browser environment, we are using JSDOM.
npm i enzyme jsdom jsdom-global enzyme-adapter-react-16 npm i @types/enzyme @types/jsdom @types/enzyme-adapter-react-16 --save-dev
(2) Creating test setup file
Node environment where mocha runs tests does not have browser properties. We first need to add types for required browser environment properties by extending interface and adding properties.Newly created globalNode object has window, document and navigator properties. All we need to do is assign JSDOM window object to the window. This will create window globally.
Here is the entire test set up code. Configuring enzyme adapter is the same as regular JavaScript.
(3) Getting the test script right
In package.json file, you can use the test script as below. Component test uses jsx file because you need to use React. Make sure to include both .ts and .tsx files.
mocha -r ts-node/register -r jsdom-global/register -r unitTestSetup.ts **/test/**/*.ts test/**/*.tsx --recursive --timeout 5000
(4) Simple test example
Here is the sample component test example. It should work by typing npm test
Common Errors
Here are the list of common errors and how to handle them.
It looks like you called mount() without a global document being loaded
- Mocha doesn’t run the test in a browser environment & enzyme’s mount API requires a DOM. JSDOM is required to simulate a browser environment in a Node environment.
‘window is not defined’
- It can be overcome by installing jsdom-global and adding -r jsdom-global/register in mocha command
Property ‘window’ does not exist on type ‘Global’ error
- When we create setup file for JSDOM (unitTestSetup.ts on the root folder), we need to add browser properties to Node global environment as it does not have browser properties. We can extend NodeJS.Global properties by adding interface and redefining the global variable with global Node variable.