React with Redux toDoList パート2

Tuyoshi Akiyama
Jul 25, 2017 · 7 min read

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


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がとびます

ここで、 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されたらページの再読込)をしない

AddTodo.propTypes = {
submitTodo: PropTypes.func.isRequired,
};

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

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

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

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

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


参考リンク

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

  • typecheck
    props の typecheckについて

感想

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

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

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

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

Tuyoshi Akiyama

Written by

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade