これは、堅牢なテストソリューションのためにJestEnzymeの両方を使用してReact/Reduxアプリをテストする4部構成のシリーズのパート2です。 このパートでは、Reactコンポーネントをテストする方法に関するいくつかの簡単な例を取り上げます。

シリーズ

Reactコンポーネントのテストに関しては、通常のJavaScript関数のテストよりも少し複雑になります。 幸いなことに、コンポーネントのパブリックインターフェイスをテストしているだけです。 あなたはまだ入力を持っています(props)および出力(レンダリングされるもの)。

このシリーズのパート1を読んでフォローすると、さらに良いニュースがあります。 すでにJestとEnzymeがインストールおよびセットアップされています。 これらの2つのライブラリを組み合わせると、Reactコンポーネントをテストする際の多くの苦痛が抽象化されます。

何をインポートするか

__tests __ / components / GatorMenu.test.js
import React from 'react';
import { shallow } from 'enzyme';
import toJson from 'enzyme-to-json';
import configureStore from 'redux-mock-store'; // Smart components

// Component to be tested
import GatorMenu from '../../components/GatorMenu';

...

The shallow() Enzymeのメソッドは、現在のノードをレンダリングし、その周りに浅いラッパーを返します。 これにより、ユニットテストに忠実であり続け、コンポーネントのみをテストし、子をアサートしません。

The toJson() 酵素からjsonへのメソッドは、酵素ラッパーをJestスナップショットテストと互換性のある形式に変換します。

The configureStore() redux-mock-storeのメソッドは、Reduxストアとのやり取りをモックアウトするために使用されます。 ストアに接続されているスマートコンポーネントにのみ必要です。

コンポーネントがレンダリングすることをテストします

__tests __ / components / GatorMenu.test.js
...

describe('<GatorMenu />', () => {
  describe('render()', () => {
    test('renders the component', () => {
      const wrapper = shallow(<GatorMenu />);
      const component = wrapper.dive();

      expect(toJson(component)).toMatchSnapshot();
    });
  });
});

...

dive()メソッドは、現在のラッパーのレンダリングされた非DOMの子を返します。 これは、コンポーネントが別のコンポーネントを div 要素のようなものでラップしている場合に役立ちます。テストに関心があるのは、その内部コンポーネントです。

イベントのシミュレーション

これは、 click レンダリングされたコンポーネントのイベント。 浅くレンダリングされたコンポーネントを使用します find 要素を見つけてから呼び出すメソッド simulate 文字列として渡されたイベントの名前を持つ、返された要素のメソッド:

__tests __ / components / GatorButton.test.js
...

describe('<GatorButton />', () => {
  describe('onClick()', () => {
    test('successfully calls the onClick handler', () => {
      const mockOnClick = jest.fn();
      const wrapper = shallow(
        <GatorButton onClick={mockOnClick} label="Eat Food" />
      );
      const component = wrapper.dive();

      component.find('button').simulate('click');

      expect(mockOnClick.mock.calls.length).toEqual(1);
    });
  });
});

...

jest.fn()メソッドを使用すると、関数を簡単にモックしてスパイすることができます。

スマートコンポーネントのテスト

アクションとレデューサーをカバーするテストを通じて、Reduxストアとの相互作用をテストすることをお勧めします。 コンポーネントのテストは、レンダリングされる内容とクライアント側の動作に焦点を合わせてください。 そうは言っても、スマートコンポーネント内でストアとのやり取りをテストできます。

__tests __ / components / GatorAvatar.test.js
import { Avatar } from 'react-native-elements';

...

const mockStore = configureStore();
const initialState = {
  selectReducer: {
    selectedAvatar: 0,
  },
  avatars: [
    {
      name: 'Green Gator',
      image: 'https://cdn.alligator.io/images/avatars/green-gator.jpg',
    },
    {
      name: 'Yellow Gator',
      image: 'https://cdn.alligator.io/images/avatars/yellow-gator.jpg',
    },
    {
      name: 'Blue Gator',
      image: 'https://cdn.alligator.io/images/avatars/blue-gator.jpg',
    },
  ],
};
const store = mockStore(initialState);

describe('<GatorAvatar />', () => {
  test('dispatches event to show the avatar selection list', () => {
    const wrapper = shallow(<GatorAvatar store={store} />);
    const component = wrapper.dive();

    component.find(Avatar).props().onPress();

    expect(store.getActions()).toMatchSnapshot();
  });
});

...

ご覧のとおり、を呼び出すことでコンポーネントの小道具にアクセスできます props() 要素に。

ボーナスのヒント!

Jestの前は、多くの単体テストがMochaまたはJasmineで作成されていました。 特に、を使用している場合は、これらのテストをJestに簡単に移植できます。 expect() アサーションのフレーバー。 あなたも保つことができます it() 代わりに test() そして彼らは走るべきです。 または、物事を更新したい場合 test() 次に、検索と置換があなたの親友です。

次は何ですか?

このシリーズのパート1では、JestとEnzymeのインストールとセットアップの方法を紹介しました。 パート3では、Reduxアクションのテストに移ります。 パート4で終了し、Reduxレデューサーをテストする方法を紹介します。 乞うご期待!