Getting started with Unit testing in React Native
Tags: reactnative, testing, javascript
Published: 2022-01-01 12:23:26

## What is Unit testing?

Unit testing is the practice of testing small, isolated pieces of code, like individual functions or classes.

The great thing about unit testing is that they are quick to write and run. Therefore, as you work, you get fast feedback about whether your tests are passing or not.

## Which Is the Best Framework for unit testing?

The most popular JavaScript frameworks are [Jasmine](https://jasmine.github.io/), [Enzyme](https://enzymejs.github.io/enzyme/), [Jest](https://jestjs.io/), and [Mocha](https://mochajs.org/). But we will be using [Jest](https://jestjs.io/) for unit-testing.

**Why Jest**

[Jest](https://jestjs.io/) is a delightful JavaScript Testing Framework with a focus on simplicity. Facebook developed the Jest unit testing framework which is the best option for most React Native projects.

React Native [docs](https://reactnative.dev/docs/testing-overview) also recommends Jest for testing React Native applications.

**Installation**

Jest setup has been included by default when running [react-native init](https://reactnative.dev/blog/2016/11/08/introducing-button-yarn-and-a-public-roadmap#speed-up-react-native-init-using-yarn) so we don't need to do any extra steps for installation.

## Implementation

Now, we will first create a `helper.js` file inside the `src` folder which will contain `addTodo`, `findTodoItem`, `updateTodo`, and `removedTodo` functions.

**helper.js**

**1.)** **Test case for add Todo**
```
export const addTodo = (list, item) => [item, ...list];

```
After that, we will create a `helper.test.js` file for ensuring that these functions are working properly or not.

```
import {expect, it} from '@jest/globals';
import {v4 as uuidv4} from 'uuid';

import {addTodo} from './helper';

describe('todo', () => {
  const id1 = uuidv4();
  const id2 = uuidv4();
  const id3 = uuidv4();
  it('should add todo to the list', () => {
    const startTodos = [
      {id: id1, task: 'task-1'},
      {id: id2, task: 'task-2'},
    ];

    const newTodo = {id: id3, task: 'task-3'};
    const expected = [
      {id: id3, task: 'task-3'},
      {id: id1, task: 'task-1'},
      {id: id2, task: 'task-2'},
    ];

    const result = addTodo(startTodos, newTodo);
    expect(result).toEqual(expected);
  });
  });

```

Let's understand the code written inside the `helper.test.js` file step-by-step.

i.) ```
    import {expect, it} from '@jest/globals';
    import {v4 as uuidv4} from 'uuid';

    import {addTodo} from './helper';
   ```
  `expect` and `it` are jest methods.
  `uuid` package is used for generating a unique ID.
  `addTodo` is a function which we want to test whether it returns the correct value or not.

ii.) ```
    describe('todo', () => {}
   ```
`describe(name, fn)` creates a block that `groups` together with several related tests. so we create a group named todo which includes todo-related tests like `addTodo`, `delete Todo`, etc.

iii.) ```
     const id1 = uuidv4();
     const id2 = uuidv4();
     const id3 = uuidv4();
   ```
Here, we create three different unique IDs using the uuid package.

iv.) 

```
    it('should add todo to the list', () => {
    const startTodos = [
      {id: id1, task: 'task-1'},
      {id: id2, task: 'task-2'},
    ];

    const newTodo = {id: id3, task: 'task-3'};
    const expected = [
      {id: id3, task: 'task-3'},
      {id: id1, task: 'task-1'},
      {id: id2, task: 'task-2'},
    ];

    const result = addTodo(startTodos, newTodo);
    expect(result).toEqual(expected);
  });
   ```

`it` is for testing.

`startTodos` variable defines the initial todo-list which has 2 items.

`newTodo` variable defines a new todo value which we want to add inside the todo-list.

`expected` variable defines that after adding a new todo value to the existing todo list, the new todo-list should be equal to our `expected` list.

`result` variable stores the value that is returned by `addTodo` function.

`expect(result).toEqual(expected);` If our expected value is equal to the `result` then our test should be passed and if our expected value is not equal to the result then our test should be failed.


**2.** **Test case for find an item from todo-list**

```
export const findTodoItem = (list, id) =>
  list.find(listItem => listItem.id === id);
```

`let's write the test case for above function.`


```
it('find item by id from todos list', () => {
    const startTodos = [
      {id: id1, task: 'task-1'},
      {id: id2, task: 'task-2'},
      {id: id3, task: 'task-3'},
    ];

    const expectedTodoItem = {id: id2, task: 'task-2'};

    const result = findTodoItem(startTodos, id2);

    expect(result).toEqual(expectedTodoItem);
  });
```

`Let's understand the above test case step-by-step`.


`startTodos` variable defined that the initial todo list.

`expectedTodoItem` variable defined that our expected todo-item.

`result` variable store the value that `findTodoItem` function returns. 

`expect(result).toEqual(expectedTodoItem)` If our expected value is equal to result then our test should be passed and if our expected value shouldn't equal to result then our test should be failed.


**3.** **Test case for update an particular item from todo-list**

```
export const updateTodo = (list, updatedListItem) => {
  const updatedList = list.map(listItem =>
    listItem.id === updatedListItem.id ? updatedListItem : listItem,
  );

  return updatedList;
};
```

`let's write the test case for above function.`


```
it('update todo should update todo by id', () => {
    const startTodos = [
      {id: id1, task: 'task-1'},
      {id: id2, task: 'task-2'},
      {id: id3, task: 'task-3'},
    ];

    const updatedTodo = {id: id2, task: 'task-2-updated-successfully'};

    const expectedTodos = [
      {id: id1, task: 'task-1'},
      {id: id2, task: 'task-2-updated-successfully'},
      {id: id3, task: 'task-3'},
    ];

    const result = updateTodo(startTodos, updatedTodo);
    expect(result).toEqual(expectedTodos);
  });
```

`let's understand the above test case step-by-step`.


`startTodos` variable store the initial todo list.

Update the existing todo-item and stored in the `updatedTodo`.

`result` variable store the value that `updateTodo` function returns.

`expectedTodos` variable defined that our new updated todo-list.

`expect(result).toEqual(expectedTodos)` If our expected value is equal to result then our test should be passed and if our expected value shouldn't equal to result then our test should be failed.


**4. Test case for delete an particular item from todo-list**

```
 export const removedTodo = (list, id) =>
  list.filter(listItem => listItem.id !== id);
```

`let's write the test case for above function.`.


```
it('removeTodo should remove todo from todos by id', () => {
    const startTodos = [
      {id: id1, task: 'task-1'},
      {id: id2, task: 'task-2'},
      {id: id3, task: 'task-3'},
    ];

    const expected = [
      {id: id1, task: 'task-1'},
      {id: id3, task: 'task-3'},
    ];

    const result = removedTodo(startTodos, id2);
    expect(result).toEqual(expected);
  });
```

`let's understand the above test case step-by-step`.

`startTodos` variable store the initial todo list.

`expected` variable store the expected todo list after deleting the particular todo item.

`result` variable store the value that `removedTodo` function returns.

`expect(result).toEqual(expected)` If our expected value is equal to result then our test should be passed and if our expected value shouldn't equal to result then our test should be failed.

**Conclusion**

Run `yarn run test` command and you see all test case are passed.
 
In this example we write the unit test case for Todo App which includes test case for AddTodo , UpdateTodo and DeleteTodo functions.

If you want to write unit test then be ensure to write[ Pure Functions](https://www.geeksforgeeks.org/pure-functions-in-javascript/).

Divide the logic of complex functions into a small piece of pure functions then it's very easy to write a unit test case.

`For writing test cases of a pure function you should follow these steps:-`

- Define your initial value.
- Define your expected value after the function executes.
- Call the function with expected params and store the value returned by the function.
- Check if your expected value is equal to the result or not.
- If they are equal then the test will pass, otherwise the test will fail.

Finally, here is the full source code of this [Todo app](https://github.com/binitgurzu/TodoApp)