📜  react native tdd emzyme - Javascript (1)

📅  最后修改于: 2023-12-03 14:46:56.965000             🧑  作者: Mango

React Native TDD Enzyme

Introduction

React Native is a popular framework utilized for developing mobile applications using Javascript. Test-driven development (TDD) is a testing approach that emphasizes writing tests before writing actual code, which helps increase confidence in the produced code.

Enzyme is a testing utility for React that provides various test functionalities, such as shallow rendering, full rendering, and more. In this article, we will explore how to use Enzyme for testing React Native components through TDD.

Prerequisites
  • Familiarity with React Native
  • Basic knowledge of unit testing and TDD
  • Basic knowledge of Enzyme
Installation

To install Enzyme for React Native, we need to install both the enzyme and react-native-enzyme packages. We can do this by running the following command in our project directory:

npm install --save-dev enzyme react-native-enzyme

We also need to install jest-enzyme, which provides additional matchers for our Enzyme tests:

npm install --save-dev jest-enzyme

Finally, we need to configure Jest to use Enzyme and jest-enzyme. We can do this by creating a setupTests.js file in our /src directory with the following contents:

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { configure } from 'enzyme';
import { set } from 'jest-extended';

configure({ adapter: new Adapter() });
set('react-native', true);
Basics of Enzyme

Before diving into TDD, let's explore the basics of Enzyme for React Native components.

Shallow Rendering

Shallow rendering allows us to test the component in isolation without rendering its child components. For example, we can create a shallow rendering of a Button component like this:

import { shallow } from 'enzyme';
import Button from '../Button';

describe('Button', () => {
  test('renders correctly', () => {
    const wrapper = shallow(<Button title="Press me" />);
    expect(wrapper).toMatchSnapshot();
  });
});

In the above code, we imported the shallow function from Enzyme to create a shallow rendering of our Button component. We then used Jest's toMatchSnapshot matcher to compare the rendered component with a snapshot of the expected result.

Full Rendering

Full rendering allows us to test the component and its child components. We can create a full rendering of a ScrollView component with a child Text component like this:

import { mount } from 'enzyme';
import { ScrollView, Text } from 'react-native';

describe('ScrollView', () => {
  test('renders children correctly', () => {
    const wrapper = mount(
      <ScrollView>
        <Text>Hello, world!</Text>
      </ScrollView>,
    );
    expect(wrapper).toMatchSnapshot();
  });
});

In the above code, we imported the mount function from Enzyme to create a full rendering of our ScrollView component. We then used Jest's toMatchSnapshot matcher to compare the rendered component with a snapshot of the expected result.

TDD with Enzyme

Now that we have explored the basics of Enzyme, let's dive into TDD for React Native components.

Writing Tests

When writing tests for our React Native components, we follow the TDD approach of writing tests before writing code. For example, let's say we want to create a TextInput component that accepts a placeholder prop, which renders a placeholder text when the input is empty.

We would start by writing a test that fails because the component does not exist:

import { shallow } from 'enzyme';
import TextInput from '../TextInput';

describe('TextInput', () => {
  test('renders correctly', () => {
    const wrapper = shallow(<TextInput placeholder="Enter text" />);
    expect(wrapper).toMatchSnapshot();
  });
});

In the above code, we imported our TextInput component and attempted to render it with a placeholder prop. Since the component does not exist yet, the test should fail.

We can then proceed to writing our TextInput component:

import React from 'react';
import { TextInput as RNTextInput } from 'react-native';
import PropTypes from 'prop-types';

const TextInput = ({ placeholder }) => (
  <RNTextInput placeholder={placeholder} />
);

TextInput.propTypes = {
  placeholder: PropTypes.string.isRequired,
};

export default TextInput;

Note that we imported PropTypes from the prop-types package to ensure that our TextInput component is correctly receiving a placeholder prop.

We can then rerun our test, which should now pass.

Testing User Interactions

We can also use Enzyme to test user interactions with our components. For example, let's say we want to test that our Button component calls a onPress callback when it is pressed.

We would start by writing a test that simulates the button press:

import { shallow } from 'enzyme';
import Button from '../Button';

describe('Button', () => {
  test('calls onPress callback on press', () => {
    const onPress = jest.fn();
    const wrapper = shallow(<Button title="Press me" onPress={onPress} />);
    wrapper.simulate('press');
    expect(onPress).toHaveBeenCalled();
  });
});

In the above code, we imported our Button component and defined a mock onPress function using Jest's fn function. We then rendered the component with the onPress prop and simulated a press event using Enzyme's simulate function. Finally, we used Jest's toHaveBeenCalled matcher to ensure that our onPress function was called.

Conclusion

In this article, we explored how to use Enzyme to apply the TDD approach to testing React Native components. We covered the basics of shallow and full rendering, and demonstrated how to write tests and test user interactions with our components. As a result, we can increase our confidence in the reliability and functionality of our React Native applications.