Create react app typescript: testing with jest and enzyme
Tags: unittesting, createreactapp, enzyme, jest
Published: 2020-02-28 10:21:48

---
title: Create react app typescript: testing with jest and enzyme
published: true
date: 2020-02-26 16:11:02 UTC
tags: unit-testing,create-react-app,enzyme,jest
canonical_url: https://medium.com/@feralamillo/create-react-app-typescript-testing-with-jest-and-enzyme-869fdba1bd3
---

![](https://cdn-images-1.medium.com/max/791/1*zE6WyFAE-JCsfb8bMogieQ.png)<figcaption>Istanbul coverage report</figcaption>

Get your unit testing configuration ready in less than 10 minutes. In this article, you can find how to get jest and enzyme ready for your tests and Istanbul to collect the coverage.

### Pre-requisite

As a first step, I’m going to install create react app with the typescript template.

```
npx create-react-app my-project --template typescript
```

It will take some time installing. I have included two versions, one for non-ejected versions of create-react-app and one for the ejected versions. I think the best is to avoid ejecting create-react-app as all the webpack config is taken care of. So, if you haven’t ejected, don’t do it!

### Step 1: Install dependencies

```
npm i -D ts-jest jest-fetch-mock enzyme enzyme-adapter-react-16 enzyme-to-json [@types/enzyme](http://twitter.com/types/enzyme) [@types/enzyme-adapter-react-16](http://twitter.com/types/enzyme-adapter-react-16) --save-exact
```

### **Step 2: Include config files**

#### Without ejecting

package.json

```
"jest": {
    "collectCoverageFrom": [
      "src/\*\*/\*.{js,jsx,ts,tsx}",
      "!src/\*\*/\*.d.ts",
      "!src/index.tsx",
      "!src/serviceWorker.ts"
    ],
    "coveragePathIgnorePatterns": [
      "./src/\*/\*.types.{ts,tsx}",
      "./src/index.tsx",
      "./src/serviceWorker.ts"
    ],
    "coverageReporters": [
      "json",
      "lcov",
      "text-summary",
      "clover"
    ],
    "coverageThreshold": {
      "global": {
        "statements": 95,
        "branches": 95,
        "lines": 95,
        "functions": 95
      }
    },
    "snapshotSerializers": [
      "enzyme-to-json/serializer"
    ],
    "transform": {
      "^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node\_modules/ts-jest"
    },
    "transformIgnorePatterns": [
      "[/\\\\]node\_modules[/\\\\].+\\.(js|jsx|ts|tsx)$",
      "^.+\\.module\\.(css|sass|scss)$"
    ],
    "moduleNameMapper": {
      "^react-native$": "react-native-web",
      "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy",
      "src/(.\*)$": "<rootDir>/src/$1"
    }
  }
```

src/setupTests.ts

```
import Enzyme from 'enzyme';
import ReactSixteenAdapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new ReactSixteenAdapter() });
```

#### Ejected version

In case you decide to eject create-react-app

config/jest/setupEnzyme.ts

```
import Enzyme from 'enzyme';
import ReactSixteenAdapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new ReactSixteenAdapter() });
```

config/jest/setupJest.ts

```
import { GlobalWithFetchMock } from 'jest-fetch-mock';

const customGlobal: GlobalWithFetchMock = global as GlobalWithFetchMock;
customGlobal.fetch = require('jest-fetch-mock');
customGlobal.fetchMock = customGlobal.fetch;
```

config/jest/typescriptTransform.js

```
// Copyright 2004-present Facebook. All Rights Reserved.
'use strict';
const tsJestPreprocessor = require('ts-jest/preprocessor');

module.exports = tsJestPreprocessor;
```

jest.config.js

```
module.exports = {
  roots: ['<rootDir>/src'],
  preset: 'ts-jest',
  globals: {
    'ts-jest': {
      diagnostics: true,
    },
  },
  collectCoverageFrom: [
    'src/\*\*/\*.{js,jsx,ts,tsx}',
    '!src/\*\*/\*.d.ts',
    '!src/serviceWorker.ts',
    '!src/setupTests.ts',
    '!src/index.tsx',
  ],
  setupFiles: ['./config/jest/setupJest.ts', './config/jest/setupEnzyme.ts'],  
  coveragePathIgnorePatterns: ['./src/\*/\*.types.{ts,tsx}'],
  coverageReporters: ['json', 'lcov', 'text-summary', 'clover'],
  coverageThreshold: {
    global: {
      statements: 95,
      branches: 95,
      lines: 95,
      functions: 95,
    },
  },
  snapshotSerializers: ['enzyme-to-json/serializer'],
  testMatch: ['<rootDir>/src/\*\*/\*.test.{js,jsx,ts,tsx}'],
  automock: false,
  transform: {
    '^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/node\_modules/ts-jest',
    '^.+\\.css$': '<rootDir>/config/jest/cssTransform.js',
    '^(?!.\*\\.(js|jsx|ts|tsx|css|json)$)':
      '<rootDir>/config/jest/fileTransform.js',
  },
  transform: {
    '^.+\\.(js|jsx|ts|tsx)$': '<rootDir>/node\_modules/ts-jest',
    '^.+\\.css$': '<rootDir>/config/jest/cssTransform.js',
    '^(?!.\*\\.(js|jsx|ts|tsx|css|json)$)':
      '<rootDir>/config/jest/fileTransform.js',
  },
  modulePaths: [],
  moduleNameMapper: {
    '^react-native$': 'react-native-web',
    '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',
    'src/(.\*)$': '<rootDir>/src/$1',
  },
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
};
```

### Step 3:  **scripts**

#### Without ejecting

package.json

```
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
**"test:coverage": "react-scripts test --coverage --runInBand --watchAll=false",**
    "eject": "react-scripts eject",
    "lint": "eslint --ext .js,.jsx,.ts,.tsx src --color",
    "format": "prettier --write src/\*\*/\*.{ts,tsx,scss,css,json}",
    "isready": "npm run format && npm run lint && **npm run test:coverage** && npm run build"
  },
```

#### Ejected version

package.json

```
  "scripts": {
    "start": "node scripts/start.js",
    "build": "node scripts/build.js",
    "test": "node scripts/test.js",
**"test:coverage": "node scripts/test.js --env=jsdom --coverage --runInBand --watchAll=false",**
    "lint": "eslint --ext .js,.jsx,.ts,.tsx src --color",
    "format": "prettier --write src/\*\*/\*.{ts,tsx,scss,css,json}",
    "isready": "npm run format && npm run lint && **npm run test:coverage** && yarn build"
  },
```

### Step 4: Creating first tests

As we already have the <App /> component with a test let’s just update that one. I prefer to always create a folder called tests to separate them from the components.

tests/App.test.tsx

```
import React from 'react';
import { shallow } from 'enzyme';

import App from '../App';

test('renders the component', () => {
  const component = shallow(<App />);

  expect(component).toMatchSnapshot();
});
```

When running npm run test a new snapshot will be created and there will be a new folder generated \_\_snapshots\_\_ with it.

![](https://cdn-images-1.medium.com/max/1006/1*vj8MxGqO8LK4Tp1q8LRP7w.png)<figcaption>running tests</figcaption>

### Improvements

I’m always looking for feedback so please leave any suggestions or recommendations below.