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, Enzyme, Jest, and Mocha. But we will be using Jest for unit-testing.
Why Jest
Jest 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 also recommends Jest for testing React Native applications.
Installation
Jest setup has been included by default when running react-native init 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.
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
Top comments (0)