Differences Between Unit Tests and Integration Tests In React Components

Testing is a crucial part of software development that helps ensure that an application is functioning correctly and is free of bugs. There are many different types of tests that can be performed on an application, and two of the most important are unit tests and integration tests.

Unit Tests

Unit tests focus on individual components or small groups of components and check that they function correctly in isolation.

The main goal of unit tests is to test the internal logic of a component and check that it behaves as expected when given certain inputs.

Unit tests are typically written using a testing framework, such as Jest or Mocha, and are run using a test runner, such as Karma or Jest.

But in this posting, we use React testing library. Because it is fast and easy to run and are used to test the smallest units of code, such as functions or methods.

For example, in a to-do list application, we could write unit tests for the individual to-do list item component to ensure that it is properly displaying the to-do text, its completion status, and properly handling the update and delete actions.

import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import TodoListItem from './TodoListItem';

describe('TodoListItem component', () => {
test('renders todo text', () => {
// Given a todo object
const todo = { id: 1, text: 'Test todo', isCompleted: false };
// When the TodoListItem component is rendered with the todo object
const { getByText } = render(<TodoListItem todo={todo} />);
// Then it should render the todo text
expect(getByText(todo.text)).toBeTruthy();
});

test('renders complete button', () => {
// Given a todo object
const todo = { id: 1, text: 'Test todo', isCompleted: false };
// When the TodoListItem component is rendered with the todo object
const { getByText } = render(<TodoListItem todo={todo} />);
// Then it should render a complete button
expect(getByText("Complete")).toBeTruthy();
});

test('calls onComplete when complete button is clicked', () => {
// Given a todo object and a mock function for onComplete
const todo = { id: 1, text: 'Test todo', isCompleted: false };
const onComplete = jest.fn();
// When the TodoListItem component is rendered with the todo object and onComplete
const { getByText } = render(<TodoListItem todo={todo} onComplete={onComplete} />);
// And the complete button is clicked
fireEvent.click(getByText("Complete"));
// Then onComplete should be called
expect(onComplete).toHaveBeenCalled();
});
});

We could also write unit tests for the add to-do form component to ensure that it is properly handling the form inputs, validation, and dispatching the action to add a new item to the list.

import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import AddTodoForm from './AddTodoForm';

describe('AddTodoForm component', () => {
test('renders form', () => {
// when the AddTodoForm component is rendered
// when the AddTodoForm component is rendered
const { getByTestId } = render(<AddTodoForm />);
// it should render a form
expect(getByTestId("add-todo-form")).toBeTruthy();
});

test('calls onSubmit when form is submitted', () => {
// Given a mock function for onSubmit
const onSubmit = jest.fn();
// When the AddTodoForm component is rendered with onSubmit
const { getByTestId } = render(<AddTodoForm onSubmit={onSubmit} />);
// And the form is submitted
fireEvent.submit(getByTestId("add-todo-form"));
// Then onSubmit should be called
expect(onSubmit).toHaveBeenCalled();
});

test('calls onChange when input is changed', () => {
// Given a mock function for onChange
const onChange = jest.fn();
// When the AddTodoForm component is rendered with onChange
const { getByPlaceholderText } = render(<AddTodoForm onChange={onChange} />);
// And the input is changed
fireEvent.change(getByPlaceholderText("Add a to-do"), { target: { value: 'new to-do' } });
// Then onChange should be called
expect(onChange).toHaveBeenCalled();
});
});

Integration Tests

Integration tests focus on how components interact with one another and with the overall application.

They test that different parts of an application work together correctly and that the communication between these parts is functioning as expected.

Integration tests are used to test an entire feature or workflow, and typically involve testing multiple components together.

For example, in a to-do list application, we could write integration tests to ensure that when a user adds a new to-do item, it correctly appears in the to-do list and that the application correctly updates the backend data store.

We could also write integration tests to ensure that the application correctly handles the deletion of to-do items and their propagation through the data flow.

import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import TodoList from './TodoList';
import { Todo } from './Todo';

describe('Todo List integration tests', () => {
test('adding a new to-do item', () => {
// Given the TodoList component is rendered
const { getByPlaceholderText, getByText } = render(<TodoList />);
// And the text field and submit button for adding a new to-do
const input = getByPlaceholderText("Add a to-do");
const submitButton = getByText("Add");
// When a new to-do is added
fireEvent.change(input, { target: { value: 'Test to-do' } });
fireEvent.click(submitButton);
// Then the new to-do should be displayed on the list
expect(getByText('Test to-do')).toBeTruthy();
});

test('completing a to-do item', () => {
// Given a todo object and the TodoList component is rendered with the todo
const todo = new Todo(1, 'Test to-do', false);
const { getByText } = render(<TodoList initialTodos={[todo]} />);
// When the complete button for the to-do is clicked
fireEvent.click(getByText('Complete'));
// Then the to-do should be marked as completed
expect(getByText('Test to-do')).toHaveClass('completed');
});

test('deleting a to-do item', () => {
// Given a todo object and the TodoList component is rendered with the todo
const todo = new Todo(1, 'Test to-do', false);
const { getByText, queryByText } = render(<TodoList initialTodos={[todo]} />);
// When the delete button for the to-do is clicked
fireEvent.click(getByText('Delete'));
// Then the to-do should no longer be displayed on the list
expect(queryByText('Test to-do')).toBeNull();
});
});

It’s worth noting that again this is a simple example that might not cover all the cases in a real world application, and the testing code needs to be adjusted to the specific requirements of the application.

Keep in mind that integration tests are slower than unit tests and more expensive to maintain because they involve setting up the interactions between multiple components, therefore, it’s a good practice to keep the number of integration tests to a minimum, and test only the most important features and workflows.

Additionally, it’s a good practice to keep the integration tests close to the real user interaction as possible. This makes them more reliable, as you’re testing the actual behavior of the application, rather than just testing the individual parts in isolation.

Conclusion

It’s important to note that both unit tests and integration tests are necessary for a robust test coverage of an application.

While unit tests are great for testing individual components and internal logic, integration tests are needed to test the interactions between different components and ensure that the overall application is functioning correctly.

In conclusion, testing is a crucial part of software development and helps ensure that an application is functioning correctly.

Unit tests and integration tests are two important types of tests that are used to test different aspects of an application.

Unit tests focus on individual components and check that they function correctly in isolation, while integration tests focus on how components interact with one another and the overall application.

Together, they ensure that an application is working correctly and catch any bugs or regressions.

Build apps with reusable components like Lego

Bit’s open-source tool help 250,000+ devs to build apps with components.

Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.

Learn more

Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:

Micro-Frontends

Design System

Code-Sharing and reuse

Monorepo

Learn more


Differences Between Unit Tests and Integration Tests In React Components was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces - Medium and was authored by Boaz Hwang

Testing is a crucial part of software development that helps ensure that an application is functioning correctly and is free of bugs. There are many different types of tests that can be performed on an application, and two of the most important are unit tests and integration tests.

Unit Tests

Unit tests focus on individual components or small groups of components and check that they function correctly in isolation.

The main goal of unit tests is to test the internal logic of a component and check that it behaves as expected when given certain inputs.

Unit tests are typically written using a testing framework, such as Jest or Mocha, and are run using a test runner, such as Karma or Jest.

But in this posting, we use React testing library. Because it is fast and easy to run and are used to test the smallest units of code, such as functions or methods.

For example, in a to-do list application, we could write unit tests for the individual to-do list item component to ensure that it is properly displaying the to-do text, its completion status, and properly handling the update and delete actions.

import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import TodoListItem from './TodoListItem';

describe('TodoListItem component', () => {
test('renders todo text', () => {
// Given a todo object
const todo = { id: 1, text: 'Test todo', isCompleted: false };
// When the TodoListItem component is rendered with the todo object
const { getByText } = render(<TodoListItem todo={todo} />);
// Then it should render the todo text
expect(getByText(todo.text)).toBeTruthy();
});

test('renders complete button', () => {
// Given a todo object
const todo = { id: 1, text: 'Test todo', isCompleted: false };
// When the TodoListItem component is rendered with the todo object
const { getByText } = render(<TodoListItem todo={todo} />);
// Then it should render a complete button
expect(getByText("Complete")).toBeTruthy();
});

test('calls onComplete when complete button is clicked', () => {
// Given a todo object and a mock function for onComplete
const todo = { id: 1, text: 'Test todo', isCompleted: false };
const onComplete = jest.fn();
// When the TodoListItem component is rendered with the todo object and onComplete
const { getByText } = render(<TodoListItem todo={todo} onComplete={onComplete} />);
// And the complete button is clicked
fireEvent.click(getByText("Complete"));
// Then onComplete should be called
expect(onComplete).toHaveBeenCalled();
});
});

We could also write unit tests for the add to-do form component to ensure that it is properly handling the form inputs, validation, and dispatching the action to add a new item to the list.

import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import AddTodoForm from './AddTodoForm';

describe('AddTodoForm component', () => {
test('renders form', () => {
// when the AddTodoForm component is rendered
// when the AddTodoForm component is rendered
const { getByTestId } = render(<AddTodoForm />);
// it should render a form
expect(getByTestId("add-todo-form")).toBeTruthy();
});

test('calls onSubmit when form is submitted', () => {
// Given a mock function for onSubmit
const onSubmit = jest.fn();
// When the AddTodoForm component is rendered with onSubmit
const { getByTestId } = render(<AddTodoForm onSubmit={onSubmit} />);
// And the form is submitted
fireEvent.submit(getByTestId("add-todo-form"));
// Then onSubmit should be called
expect(onSubmit).toHaveBeenCalled();
});

test('calls onChange when input is changed', () => {
// Given a mock function for onChange
const onChange = jest.fn();
// When the AddTodoForm component is rendered with onChange
const { getByPlaceholderText } = render(<AddTodoForm onChange={onChange} />);
// And the input is changed
fireEvent.change(getByPlaceholderText("Add a to-do"), { target: { value: 'new to-do' } });
// Then onChange should be called
expect(onChange).toHaveBeenCalled();
});
});

Integration Tests

Integration tests focus on how components interact with one another and with the overall application.

They test that different parts of an application work together correctly and that the communication between these parts is functioning as expected.

Integration tests are used to test an entire feature or workflow, and typically involve testing multiple components together.

For example, in a to-do list application, we could write integration tests to ensure that when a user adds a new to-do item, it correctly appears in the to-do list and that the application correctly updates the backend data store.

We could also write integration tests to ensure that the application correctly handles the deletion of to-do items and their propagation through the data flow.

import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import TodoList from './TodoList';
import { Todo } from './Todo';

describe('Todo List integration tests', () => {
test('adding a new to-do item', () => {
// Given the TodoList component is rendered
const { getByPlaceholderText, getByText } = render(<TodoList />);
// And the text field and submit button for adding a new to-do
const input = getByPlaceholderText("Add a to-do");
const submitButton = getByText("Add");
// When a new to-do is added
fireEvent.change(input, { target: { value: 'Test to-do' } });
fireEvent.click(submitButton);
// Then the new to-do should be displayed on the list
expect(getByText('Test to-do')).toBeTruthy();
});

test('completing a to-do item', () => {
// Given a todo object and the TodoList component is rendered with the todo
const todo = new Todo(1, 'Test to-do', false);
const { getByText } = render(<TodoList initialTodos={[todo]} />);
// When the complete button for the to-do is clicked
fireEvent.click(getByText('Complete'));
// Then the to-do should be marked as completed
expect(getByText('Test to-do')).toHaveClass('completed');
});

test('deleting a to-do item', () => {
// Given a todo object and the TodoList component is rendered with the todo
const todo = new Todo(1, 'Test to-do', false);
const { getByText, queryByText } = render(<TodoList initialTodos={[todo]} />);
// When the delete button for the to-do is clicked
fireEvent.click(getByText('Delete'));
// Then the to-do should no longer be displayed on the list
expect(queryByText('Test to-do')).toBeNull();
});
});

It’s worth noting that again this is a simple example that might not cover all the cases in a real world application, and the testing code needs to be adjusted to the specific requirements of the application.

Keep in mind that integration tests are slower than unit tests and more expensive to maintain because they involve setting up the interactions between multiple components, therefore, it’s a good practice to keep the number of integration tests to a minimum, and test only the most important features and workflows.

Additionally, it’s a good practice to keep the integration tests close to the real user interaction as possible. This makes them more reliable, as you’re testing the actual behavior of the application, rather than just testing the individual parts in isolation.

Conclusion

It’s important to note that both unit tests and integration tests are necessary for a robust test coverage of an application.

While unit tests are great for testing individual components and internal logic, integration tests are needed to test the interactions between different components and ensure that the overall application is functioning correctly.

In conclusion, testing is a crucial part of software development and helps ensure that an application is functioning correctly.

Unit tests and integration tests are two important types of tests that are used to test different aspects of an application.

Unit tests focus on individual components and check that they function correctly in isolation, while integration tests focus on how components interact with one another and the overall application.

Together, they ensure that an application is working correctly and catch any bugs or regressions.

Build apps with reusable components like Lego

Bit’s open-source tool help 250,000+ devs to build apps with components.

Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.

Learn more

Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:

Micro-Frontends

Design System

Code-Sharing and reuse

Monorepo

Learn more


Differences Between Unit Tests and Integration Tests In React Components was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces - Medium and was authored by Boaz Hwang


Print Share Comment Cite Upload Translate Updates
APA

Boaz Hwang | Sciencx (2023-01-12T08:46:50+00:00) Differences Between Unit Tests and Integration Tests In React Components. Retrieved from https://www.scien.cx/2023/01/12/differences-between-unit-tests-and-integration-tests-in-react-components/

MLA
" » Differences Between Unit Tests and Integration Tests In React Components." Boaz Hwang | Sciencx - Thursday January 12, 2023, https://www.scien.cx/2023/01/12/differences-between-unit-tests-and-integration-tests-in-react-components/
HARVARD
Boaz Hwang | Sciencx Thursday January 12, 2023 » Differences Between Unit Tests and Integration Tests In React Components., viewed ,<https://www.scien.cx/2023/01/12/differences-between-unit-tests-and-integration-tests-in-react-components/>
VANCOUVER
Boaz Hwang | Sciencx - » Differences Between Unit Tests and Integration Tests In React Components. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2023/01/12/differences-between-unit-tests-and-integration-tests-in-react-components/
CHICAGO
" » Differences Between Unit Tests and Integration Tests In React Components." Boaz Hwang | Sciencx - Accessed . https://www.scien.cx/2023/01/12/differences-between-unit-tests-and-integration-tests-in-react-components/
IEEE
" » Differences Between Unit Tests and Integration Tests In React Components." Boaz Hwang | Sciencx [Online]. Available: https://www.scien.cx/2023/01/12/differences-between-unit-tests-and-integration-tests-in-react-components/. [Accessed: ]
rf:citation
» Differences Between Unit Tests and Integration Tests In React Components | Boaz Hwang | Sciencx | https://www.scien.cx/2023/01/12/differences-between-unit-tests-and-integration-tests-in-react-components/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.