Testing modern ReactJS Application: Unit Testing(Part 1)
Tags: javascript, webdev, react, testing
Published: 2022-03-13 12:59:37

## Table of contents

1. [More libraries](#More libraries)
2. [Experiment Subject](#Experiment Subject)
3. [Experiment Environment](#Experiment Environment)
4. [Snapshot Testing](#Snapshot Testing)
    1. [Little bit of terminology](#Little bit of terminology)
    2. [Getting Started](#Getting Started)
    3. [Running tests](#Running tests)
5. [Useful Links](#Useful Links)

## More libraries

To append additional layer of abstraction and make our as developer life easier few extra libraries should be added to project:

- [`react-test-renderer`](https://reactjs.org/docs/test-renderer.html)
- [`@testing-library/react`](https://testing-library.com/docs/react-testing-library/intro/)
- [`@testing-library/jest-dom`](https://testing-library.com/docs/ecosystem-jest-dom)
- [`@testing-library/user-event`](https://testing-library.com/docs/ecosystem-user-event)

Open root of project in your terminal and invoke following command

npm:

```
npm install -D react-test-renderer @testing-li
brary/react @testing-library/jest-dom @testing-library/user-event
```

yarn:

```
yarn add -D react-test-renderer @testing-li
brary/react @testing-library/jest-dom @testing-library/user-event
```

## Experiment Subject

Before starting performing tests component is needed. To save time contents of mock component is provided below:

`component.jsx`
```javascript
import React from 'react';

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

## Experiment Environment

In the same folder create `component.test.jsx`. This file will contain all tests written in this post

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

describe('TestComponent', () => {
	
});
```

## Snapshot Testing

### Little bit of terminology

[Jest Documentation on Snapshot testing](https://jestjs.io/docs/snapshot-testing)

> The first time this test is run, Jest creates a snapshot file. On subsequent test runs, Jest will compare the rendered output with the previous snapshot. If they match, the test will pass. If they don't match, either the test runner found a bug in your code that should be fixed, or the implementation has changed and the snapshot needs to be updated

### Getting Started

Exactly for purpose of snapshot testing `react-test-renderer` was installed

1 - Import function `create` from `react-test-renderer` into `component.test.jsx`
```javascript
import { create } from 'react-test-renderer';
```

2 - Create test suite
```javascript
it('should match snapshot', () => {

	});
```

3 - Populate test suite
```javascript
expect(
            create(<TestComponent />)
                .toJSON()
        )
            .toMatchSnapshot();
```

What happens in test suite we created:

1. Rendering component using function `create` and passing JSX component as argument
2. On result of calling `create` calling method `toJSON` to serialise output
3. Passing serialised value to `expect` function and calling matcher `toMatchSnapshot`

Jest will process snapshot itself, no additional input from developer is needed

### Running tests

Now try to invoke script `test`

![result of yarn test after adding snapshot test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijir8g0dkj1wp9jb4xwu.png)
 
If you did everything correctly output should be nearly the same. In short, since snapshot didn't exist Jest saved it inside of `__snapshots__` directory next to test file and passed test. Run test again to see difference

![second result of yarn test](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n2qkc6dxwqhli8o18yeu.png)

Jest used existing snapshot for comparison. Now make some changes in component, e.g. change text in it and run script `test` again

![result of yarn test after changing component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zv3aofquxgrja4zvxe94.png)

Since content that is being rendered has been changed snapshot test had failed. That is exactly the purpose of snapshot tests: track down changes/errors in render process/result

Now, if we know that received change is correct, we need to update snapshot accordingly. To do that just call script `test` with argument `-u`

npm:

```
npm run test -u
```

yarn:

```
yarn test -u
```

Here is the result

![result of yarn test -u](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/56rl3nvmc4fs27a7nwnb.png)

That is everything you need to know to start with snapshot testing and apply it ещ your components

## Useful Links

- [Jest Documentation on Snapshot testing](https://jestjs.io/docs/snapshot-testing)
- [React Test Renderer Documentation](https://reactjs.org/docs/test-renderer.html)

Next time will share on how to perform more granular unit testing of components, difference between testing functional and class components and how to test react hooks