DEV Community

Cover image for The Power of Jest and React Native Testing Library Combined
Paulo Messias
Paulo Messias

Posted on

The Power of Jest and React Native Testing Library Combined

1. Introduction to Jest and React Native Testing Library

Jest is a JavaScript testing framework maintained by Facebook. It is widely used for its ease of use, comprehensive features, and integration with various JavaScript libraries.

React Native Testing Library (RNTL) is a library that provides simple and complete utilities for testing React Native components. Inspired by the React Testing Library, it focuses on tests that mimic the way users interact with the application.

2. Installation and Configuration

Configuration for React Native CLI

Installation:

To install Jest and React Native Testing Library, you can use npm or yarn:

npm install --save-dev jest @testing-library/react-native
# or
yarn add --dev jest @testing-library/react-native
Enter fullscreen mode Exit fullscreen mode

Configuration:

Create or edit the jest.config.js file in the root of the project to configure Jest:

module.exports = {
  preset: 'react-native',
  setupFilesAfterEnv: ['@testing-library/jest-native/extend-expect'],
  transformIgnorePatterns: [
    'node_modules/(?!(jest-)?react-native|@react-native|@react-native-community|@testing-library)',
  ],
  testPathIgnorePatterns: ['/node_modules/', '/android/', '/ios/'],
};
Enter fullscreen mode Exit fullscreen mode

Configuration for Expo

Installation:

For Expo projects, use the following command to install the necessary dependencies:

expo install jest @testing-library/react-native @testing-library/jest-native
Enter fullscreen mode Exit fullscreen mode

Configuration:

Create or edit the jest.config.js file in the root of the project to configure Jest specifically for Expo projects:

module.exports = {
  preset: 'jest-expo',
  setupFilesAfterEnv: ['@testing-library/jest-native/extend-expect'],
  transformIgnorePatterns: [
    'node_modules/(?!(jest-)?react-native|@react-native|@react-native-community|@expo|expo(nent)?|@unimodules)',
  ],
  testPathIgnorePatterns: ['/node_modules/', '/android/', '/ios/'],
};
Enter fullscreen mode Exit fullscreen mode

Additional Configuration for Expo Managed Workflow:

For projects using Expo's managed workflow, add the following script in package.json to ensure Jest works correctly:

"scripts": {
  "test": "jest"
}
Enter fullscreen mode Exit fullscreen mode

3. Most Used Methods and Utilities

Rendering:

  • render: Renders a component for testing.
import { render } from '@testing-library/react-native';
import MyComponent from '../MyComponent';

test('renders correctly', () => {
  const { getByText } = render(<MyComponent />);
  expect(getByText('Hello World')).toBeTruthy();
});
Enter fullscreen mode Exit fullscreen mode

Querying:

  • getByText: Finds an element by text.
  • getByTestId: Finds an element by testID.
const { getByTestId } = render(<MyComponent />);
expect(getByTestId('uniqueId')).toBeTruthy();
Enter fullscreen mode Exit fullscreen mode

Actions:

  • fireEvent: Simulates user events like press, changeText, etc.
import { fireEvent } from '@testing-library/react-native';

test('button press', () => {
  const { getByText } = render(<MyComponent />);
  fireEvent.press(getByText('Press me'));
  expect(someMockFunction).toHaveBeenCalled();
});
Enter fullscreen mode Exit fullscreen mode

4. Writing Tests

Render Test:

test('renders correctly', () => {
  const { getByText } = render(<MyComponent />);
  expect(getByText('Hello World')).toBeTruthy();
});
Enter fullscreen mode Exit fullscreen mode

Interaction Test:

test('button press changes text', () => {
  const { getByText, getByTestId } = render(<MyComponent />);
  fireEvent.press(getByText('Press me'));
  expect(getByTestId('textId').props.children).toBe('Button Pressed');
});
Enter fullscreen mode Exit fullscreen mode

Props Test:

test('renders with correct props', () => {
  const { getByText } = render(<MyComponent title="Test Title" />);
  expect(getByText('Test Title')).toBeTruthy();
});
Enter fullscreen mode Exit fullscreen mode

5. Use Case Examples

Component with API Call Test:

For components that make API calls, you can use jest.mock to mock API responses.

import axios from 'axios';
import MyComponent from '../MyComponent';

jest.mock('axios');

test('fetches and displays data', async () => {
  axios.get.mockResolvedValueOnce({ data: { title: 'Mock Title' } });

  const { findByText } = render(<MyComponent />);
  expect(await findByText('Mock Title')).toBeTruthy();
});
Enter fullscreen mode Exit fullscreen mode

Navigation Test:

To test navigation, you can use react-navigation and its mocking functionalities.

import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import MyComponent from '../MyComponent';
import { render } from '@testing-library/react-native';

const Stack = createStackNavigator();

test('navigates correctly', () => {
  const component = (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={MyComponent} />
      </Stack.Navigator>
    </NavigationContainer>
  );

  const { getByText } = render(component);
  expect(getByText('Home')).toBeTruthy();
});
Enter fullscreen mode Exit fullscreen mode

Jest and React Native Testing Library are powerful tools to ensure the quality of your React Native code. With unit and integration tests, you can catch bugs before they reach end users, increasing the reliability of your application.

Top comments (0)