Unit Testing in React Native
Unit Testing...the thing you know you should be doing but haven't got around to yet. Rather than repeatedly debugging through console logs across multiple screens and asynchronous operations, structured unit testing offers a more efficient approach.
What We'll Cover
- Library Options - Testing framework selections for React Native
- Project Structure - Organizing test files effectively
- Good Unit Test Characteristics - Best practices for test writing
- Native Module Mocking - Handling React Native-specific dependencies
Library Recommendations
I recommend @testing-library/react-native built by Callstack, which enforces testing practices aligned with react-testing-library. This library moves beyond basic snapshot testing toward user-behavior-focused assertions.
Additional setup includes @testing-library/jest-native for React Native-specific matchers like toHaveStyle and toBeDisabled.
npm install --save-dev @testing-library/react-native @testing-library/jest-native
Testing Fundamentals
A solid unit test contains three components:
- Description - Clear test purpose
- Setup - Test environment configuration
- Assertions - Expected outcome verification
Practical Example
Let's demonstrate testing a Form component that:
- Renders multiple input fields
- Updates state on text changes
- Submits collected data via callback
import React from 'react'
import { render, fireEvent } from '@testing-library/react-native'
import Form from './Form'
describe('Form', () => {
it('renders all question inputs', () => {
const { getByPlaceholderText } = render(<Form onSubmit={jest.fn()} />)
expect(getByPlaceholderText('Name')).toBeTruthy()
expect(getByPlaceholderText('Email')).toBeTruthy()
})
it('submits form with updated values', () => {
const mockSubmit = jest.fn()
const { getByPlaceholderText, getByText } = render(
<Form onSubmit={mockSubmit} />
)
fireEvent.changeText(getByPlaceholderText('Name'), 'John')
fireEvent.changeText(getByPlaceholderText('Email'), 'john@example.com')
fireEvent.press(getByText('Submit'))
expect(mockSubmit).toHaveBeenCalledWith({
name: 'John',
email: 'john@example.com'
})
})
})
Native Module Mocking
React Native has many native modules that won't work in a Jest environment. You'll need to mock them:
// jest.setup.js
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper')
jest.mock('@react-native-async-storage/async-storage', () =>
require('@react-native-async-storage/async-storage/jest/async-storage-mock')
)
Resources
Example repository: github.com/Staceadam/blog-examples