React with Redux toDoList パート2

Tuyoshi Akiyama
7 min readJul 25, 2017

--

前回の記事の続きになります。また、以下の記事を参考に、進めていきます。

to doリストの画面を作っていきます

e2etest/test.js

const expect = require('chai').expect;describe('TodoList App', () => {
it('Should load with the right title', () => {
...
});

it('Should allow me to create a Todo', () => {
const todoText = 'Get better at testing';
browser.url('http://localhost:3000/');
browser.element('.todo-input').setValue(todoText);
browser.click('.todo-submit');
const actual = browser.element('.todo-text').getText();
expect(actual).to.equal(todoText);
});

処理内容としては

  • 指定したページに、browserがとびます
  • .todo-inputの名前を持つ要素を探して、変数todoTextを入れます。
  • .todo-submitをbrowserが押下
  • .todo-text要素を探して、その値を定数acutualにいれます。
  • 定数actualと変数todoTextを比較して、等しければtrueを返します。

ここで、 yarn run e2e-tests を行い、failingすることを確認します。

では実際に上のエラーを出ないよう、コンポーネントを作成していきます。

まず、src/components/addTodo/配下にからファイルindex.jpをつくります

次に、テストを以下の用に書いていきます。

src/components/addTodo/test.js

/* global expect, it, describe */import React from 'react';
import { shallow } from 'enzyme';
import AddTodo from '.';
describe('AddTodo component', () => {
it('Should render successfully', () => {
const component = shallow(<AddTodo />);
expect(component.exists()).toEqual(true);
});
});

処理内容としては、

AddTodoコンポーネントをshallow(コンポーネントそれ自体を)してきたものをcomponent変数に入れます。

その変数が存在してれば、つまりAddTodoコンポーネントがあれば、trueを返します。

上のテストを作り終えたら、 yarn run test を行います。

testはエラーを出すので、それに合わせて、コードを書いていきます。

src/components/addTodo/index.js

import React from 'react';const AddTodo = () => (
<div />
);
export default AddTodo;

以下同様に、submit/inputボタン、またフォームをそれぞれテストを書きながら作っていきます。

フォームのテスト、コードについて詳しく見ていきます。

src/components/addTodo/test.js

it('Should call the submitTodo function when clicked', () => {
const submitMock = jest.fn();
const component = mount(<AddTodo submitTodo={submitMock} />);
expect(submitMock.mock.calls.length).to.equal(0);
component.find('form').simulate('submit');
expect(submitMock.mock.calls.length).to.equal(1);
});

変数submitMockにjest.fn()を代入することで、便利なヘルパー関数を使っていくことができます。

詳細については、こちらのドキュメントで確認出来ます。

また変数componentに、mount(full rendering)した<AddTodo submitTodo={submitMock} />を代入しているので、

event から preventDefault() といったフォームのsubmissionにアクセスできます。

また値を渡してもいるので、フォーム上でもsubmitMockが使えることができます。

次のコードが、上のテストに対応したAddTodoコンポーネントの表示になります。

src/components/addTodo/index.js

return (
<div>
<form
onSubmit={(event) => {
event.preventDefault();
submitTodo(input.value);
input.value = '';
}}
>
<input
className="todo-input"
ref={(element) => {
input = element;
}}
/>
<button type="submit" className="todo-submit">
Add Todo
</button>
</form>
</div>
);
ref={(element) => {
input = element;
}}

変数refにinputの値を入れることで、ReactはDOM要素に入力値をいれて、管理します。

つまり、コンポーネントの中にrefを使って保存することで、値のtrackingができるようになります。

     <form
onSubmit={(event) => {
event.preventDefault();
submitTodo(input.value);
input.value = '';
}}

また、フォームはsubmitを押された時に上のコードは以下のように処理します。

  • defaultの動作(submitされたらページの再読込)をしない
  • フォーム内の値(input.value)を引数として、submitTodo、つまりsubmitMock関数が呼ばれる。
  • フォームの値は空になる。
AddTodo.propTypes = {
submitTodo: PropTypes.func.isRequired,
};

propsの型タイプをvalidateしています。

これによって、propsのdefault値や、どの値ならvalidateするのかを設定しています。

ここでは、submitTodo関数は、関数を引数にとることが明記されています。

因みに、ここで上記のpropsのvalidationをしなかった場合、今までの全てのテストは通らないです。もちろん、eslintにも怒られます。

逆にいうと、eslintの設定さえちゃんと行っていれば、その場でエラーに気づくことができます。

参考リンク

自分用にまとめます。typecheckとrefの使い方に関しては、また後でまとめて、理解を深める必要があると感じました。

  • typecheck
    props の typecheckについて
  • Jest
    mock function(jest.fn())の使い方
  • Refs and DOM
    コード内にでてきた、refの使い方。

感想

何も設定しなくてもテストができる

yarn run testが、かなり便利でした。今のところ、これあればwebdriverIOなくも困らないと感じるくらいです。

ただし、今回のコードは画面の作成だけなので、機能を付けていくのには、またwebdriver等が必要になるのかと思います。

また、テスト駆動での開発は楽しかったです。が、これを自分でテストを考えるとなると、また違って難しいように感じました。

--

--