React Native – Testing app with Jest

Jest is a JavaScript Testing Framework used for Testing React Native applications to ensure the stability and correctness of your codebase.

Here are a steps to getting started with testing React Native using Jest:

1. Create a new React Native project using the React Native CLI

npx react-native init MyApp

2. Install Jest:

npm install --save-dev jest

3. Configure Jest: Create a file called jest.config.js in your project’s root directory and add the following content:

module.exports = {
  preset: 'react-native',
  setupFilesAfterEnv: ['@testing-library/jest-native/extend-expect'],
};

4. Write your tests: Create a directory called __tests__ in your project’s root directory. You can create test files with the .test.js or .spec.js extension

5. Run your tests: npx jest

Jest will automatically discover and run your tests, providing you with test results and coverage information.

Test component

Below example of welcome component with a view and text components and some styles.

import React, {Component} from 'react';
import {StyleSheet, Text, View} from 'react-native';

class WelcomeScreen extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>Welcome to React Native!</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    alignItems: 'center',
    flex: 1,
    justifyContent: 'center',
  },
  welcome: {
    fontSize: 20,
    margin: 10,
    textAlign: 'center',
  },
});

export default WelcomeScreen;

Snapshot Test

Now, let’s use React’s test renderer and Jest’s snapshot feature to interact with the component and capture the rendered output in snapshot file.

import React from 'react';
import renderer from 'react-test-renderer';
import WelcomeScreen from '../WelcomeScreen';

test('Welcome screen renders correctly', () => {
  const tree = renderer.create(<WelcomeScreen />).toJSON();
  expect(tree).toMatchSnapshot();
});

Now, run yarn test or jest, this will produce an output file.

exports[`Welcome screen renders correctly 1`] = `
<View
  style={
    Object {
      "alignItems": "center",
      "flex": 1,
      "justifyContent": "center",
    }
  }>
  <Text
    style={
      Object {
        "fontSize": 20,
        "margin": 10,
        "textAlign": "center",
      }
    }>
    Welcome to React Native!
  </Text>
</View>
`;

Expect

Expect is function, used every time you want to test a value. You have to use expect along with a matcher function to assert something about a value.

test('the best planet', () => {
  expect(getBestPlanet()).toBe('Earth');
});

Modifiers

Modifiers are special keywords that you can use with matchers to enhance the behavior of your test assertions. They allow you to perform more specific and nuanced checks during testing. Here some modifiers with example:

// .not
test('the best planet', () => {
  expect(getBestPlanet()).not.toBe('mars');
});

// .resolve
test('resolves to earth', () => {
  return expect(Promise.resolve('earth')).resolves.toBe('earth');
});

// .reject
test('rejects to mars', () => {
  return expect(Promise.reject(new Error('mars'))).rejects.toThrow(
    'mars',
  );
});

Matchers

Matchers are functions provided by the framework that allow you to make assertions in your tests. These assertions check whether a particular condition is true or false. Here some matchers with example:

const planet = {
  name: 'earth',
  radius: 6371,
  satellite: 'moon',
};

// .toBe(value)
test('earth has radius', () => {
   expect(planet.radius).toBe(6371);
});

function naturalSatellite(callback, name) {
  if (name === 'moon') {
    callback(name);
  }
}

// .toHaveBeenCalled()
test('natural satellite of earth', () => {
   const getNaturalSatellite = jest.fn();
   naturalSatellite(getNaturalSatellite, planet.satellite);
   expect(getNaturalSatellite).toHaveBeenCalled();
});

func notPerfectSphere(name) {
  if (name === 'earth') {
    return true;
  }
  return false;
}

// .toBeDefined() .toBeTruthy()
test('earth shape not perfect sphere', () => {
  expect(notPerfectSphere(planet.name)).toBeDefined();
  expect(notPerfectSphere(planet.name)).toBeTruthy();
});

func isRedPlanet(name) {
  if (name === 'mars') {
    return true;
  }
  return false;
}

// .toBeFalsy()
test('red planet should not be earth', () => {
  expect(isRedPlanet('earth')).toBeFalsy();
});

func getRedPlanet() {
  return 'mars';
}

// .toEqual(value)
test('red planet should be mars', () => {
  expect(getRedPlanet()).toEqual('mars');
});

Mock Functions

let you spy on the behavior of a function that is called indirectly by some other code, rather than only testing the output.

You can create a mock function with jest.fn().

// mockFn.mockName(name)
const mockFn = jest.fn().mockName('mockedFunction');
expect(mockFn).toHaveBeenCalled();

// mockFn.mockReturnValue(value)
const mock = jest.fn();
mock.mockReturnValue(123);
mock(); // 123

// mockFn.mockReturnValueOnce(value)
const mockFn = jest
  .fn()
  .mockReturnValue('default')
  .mockReturnValueOnce('first call')
  .mockReturnValueOnce('second call');
mockFn(); // 'first call'
mockFn(); // 'second call'
mockFn(); // 'default'
mockFn(); // 'default'

// mockFn.mockResolvedValue(value)
test('async test', async () => {
  const asyncMock = jest.fn().mockResolvedValue(123);

  await asyncMock(); // 123
});

// mockFn.mockResolvedValueOnce(value)
test('async test', async () => {
  const asyncMock = jest
    .fn()
    .mockResolvedValue('default')
    .mockResolvedValueOnce('first call')
    .mockResolvedValueOnce('second call');

  await asyncMock(); // 'first call'
  await asyncMock(); // 'second call'
  await asyncMock(); // 'default'
  await asyncMock(); // 'default'
});

// mockFn.mockRejectedValue(value)
test('async test', async () => {
  const asyncMock = jest
    .fn()
    .mockResolvedValue('default')
    .mockResolvedValueOnce('first call')
    .mockResolvedValueOnce('second call');

  await asyncMock(); // 'first call'
  await asyncMock(); // 'second call'
  await asyncMock(); // 'default'
  await asyncMock(); // 'default'
});

// mockFn.mockRejectedValue(value)
test('async test', async () => {
  const asyncMock = jest
    .fn()
    .mockRejectedValue(new Error('Async error message'));

  await asyncMock(); // throws 'Async error message'
});

Conclusion

In this blog, we have learned how to set up Jest in a React Native project and write tests using Jest. Testing is important for ensuring the quality and stability of your React Native applications. And by using Jest, you can easily write tests for your components and improve the overall reliability of your app.

Reference: https://jestjs.io/docs/getting-started

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.