Testing modern ReactJS Application: Setting Up
Tags: javascript, webdev, react, testing
Published: 2022-03-13 09:05:22

## Table of contents
1. [Foreword](#Foreword)
   1. [Do you have to read this](#Do you have to read this)
   2. [Create React App](#Create React App)
   3. [TypeScript](#TypeScript)
2. [Your way of ReactJS](#Your way of ReactJS)
3. [How to bootstrap ReactJS App](#How to bootstrap ReactJS App)
4. [Installing and configuring Jest](#Installing and configuring Jest)
5. [Holy Babel](#Holy Babel)

## Foreword

### Do you have to read this
If you have already Jest installed and configured you can skip this part of series

### Create React App

I am completely aware that `create-react-app` provides Jest configuration out of the box, but this fact breaks the whole point of this series. I want to demonstrate how to install everything from scratch.

### TypeScript

Regarding TypeScript - I will cover all additional configuration needed, but firstly I want to focus on setting up essentials using JavaScript only

## Your way of ReactJS

If for some reason you don't want to use Vite for app bootstrapping or you are already having ReactJS app you can skip this part of series as it does not matter really what bundling tool you are using.

In case you are going to scaffold application your way be aware you can face issues not covered in this tutorial series

## How to bootstrap ReactJS App
Our initial goal is to bootstrap ReactJS application quickly without any need to perform manual configurations ourselves.

For this tutorial I am going to use starter based on such bundling tool as [Vite](https://vitejs.dev/). Basically, it will only matter only on this step since [Jest](https://jestjs.io/)(testing framework) invokes all tests in it's own environment and does not care what bundling tool you are using for development

Use following command to scaffold ReactJS application named `react-testing-app`:

npm:

```
npm create vite@latest react-testing-app -- --template react
```

yarn:

```
yarn create vite react-testing-app --template react
```
Once you are done with this step follow given instructions.

1. `cd react-testing-app/`
2. `yarn`(just `yarn` and it will start installation by default)/`npm install`

After all previous steps you can invoke script `dev` to start up dev server:

npm:

```
npm run dev
```
yarn:

```
yarn dev
```

And make sure that application starts properly and running on port 3000

If everything works properly you can stop dev server and proceed further with tutorial

## Installing and configuring Jest

First thing we need is Jest. In short, Jest is testing framework. I won't go deep in details regarding Jest, this post is about bit different thing.

Firstly, let's add Jest as development dependency to our project and install it

npm:

```
npm install -D --save jest
```
yarn:

```
yarn add -D jest
```

Once command is completed you can open your `package.json` and make sure that Jest is now listed in your `devDependencies`:

```json
...
"devDependencies": {
  ...
  "jest": "^27.5.1"
}
...
```

Now we can initialize Jest. Basically, it will create `jest.config.js` that we are going to use for Jest configuration

Run following command to start Jest initialization:

npm:

```
npx jest --init
```
yarn:

```
yarn jest --init
```

You will be prompted to answer few questions. Answers provided below
![List of questions and answers to them for Jest configuration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f34cr97h8ue44p7apnjg.png)

When you are done just create `App.test.js` inside of `src` directory with following contents

```javascript
describe('jest', () => {
    it('should work', () => {
        expect(2).toBe(2);
    })
});
```
And then execute script test to verify that Jest runs test properly

npm:

```
npm run test
```
yarn:

```
yarn test
```

Result will be as follows
![Result of Jest invocation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t7wqdicfg37qut5kxe24.png)

## Holy Babel

[`Babel`](https://babeljs.io/) will be responsible for turning JSX and other modern language features to such state it can be understood by runtime environment Jest using under the hood since currently if you try to import file with JSX into test file you will get an error

Firstly, adding Babel itself and few additional packages as development dependencies to our project

npm:

```
npm install -D babel-jest @babel/core @babel/preset-env @babel/preset-react
```
yarn:

```
yarn add -D babel-jest @babel/core @babel/preset-env @babel/preset-react
```

Then create file named `babel.jest.config.js`. The reason behind such name is to avoid possible collision with default `babel.config.js`. For example NextJS automatically starts using babel compiler if it sees `babel.config.js` in root of project

Set following content of `babel.jest.config.js`:

```javascript
module.exports = {
  presets: [
		['@babel/preset-env', {targets: {node: 'current'}}],
		'@babel/preset-react'
	],
};
```

In short such we are telling Babel to use following presets while transpiling our JavaScript code

Now we need explicitly tell Jest to use this babel configuration for transpiling JS code. To do that open `jest.config.js`, find `transform` key, uncomment and replace `undefined` with following:

```json
"\\.(js|jsx)$": ["babel-jest", { "configFile": "./babel.jest.config.js" }]
```
As a result you should have:

```json
...
transform: {
    "\\.(js|jsx)$": ["babel-jest", { "configFile": "./babel.jest.config.js" }]
  },
...
```

Now, to test whether Jest is configured properly for parsing modern JS and JSX, create file `component.jsx`, export some mock component from there, import into `App.test.js` and invoke `test` script. Here are contents of my `component.jsx` and `App.test.js` respectively:

```javascript
import React from 'react';

export default function TestComponent() {
	return (
		<div>
			Test Component
		</div>
	);
};
```

```javascript
import React from 'react';
import TestComponent from './component';

describe('jest', () => {
    it('should work', () => {
        expect(2).toBe(2);
    })
});
```

`npm run test`/`yarn test` result:

![yarn test result after setting up babel](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/623yxmor6ds1g5epjnrw.png)
 
If you have similar successful output, congratulations, you have set up Jest and Babel properly for transpiling and understanding JSX. Now you are ready to start testing your application.

Next time I'm going to cover unit testing of components using `react-test-renderer`, `@testing-library/react`, `@testing-library/jest-dom` and `@testing-library/user-event`