前回の記事で action と reducers の記述方法を学びました。 ここでは components を定義します。
components は redux に無関係で純粋に react のみを使ってみます。
準備
npm install --save-dev jsdom react-addons-test-utils
components
create src/components/MemoList.js:
import React, { Component, PropTypes } from 'react' class MemoList extends Component { render() { return ( <ul className="memoList"> {this.props.memos.map(memo => <li key={memo.id}>{memo.text}</li> )} </ul> ) } } MemoList.propTypes = { memos: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.number.isRequired, text: PropTypes.string.isRequired }).isRequired).isRequired, } export default MemoList
create src/components/AddMemo.js:
import React, { Component, PropTypes } from 'react' class AddMemo extends Component { propTypes: { handleMemoSubmit: PropTypes.func.isRequired } render () { let input; return ( <div> <form onSubmit={(e) => { e.preventDefault() if (!input.value.trim()) { return } this.props.handleMemoSubmit(input.value) input.value = '' }}> <input ref={node => { input = node }} /> <button type="submit">Add Memo</button> </form> </div> ) } } export default AddMemo
test
npm install --save-dev react-addons-test-utils
create test/test_components.js:
import {jsdom} from 'jsdom' global.document = jsdom('<html><body></body></html>') global.window = document.defaultView global.navigator = window.navigator import assert from 'assert' import React from 'react' import ReactTestUtils, {createRenderer} from 'react-addons-test-utils' import MemoList from '../src/components/MemoList' import AddMemo from '../src/components/AddMemo' describe('Memo Component', function () { it('MemoList', function () { const renderer = createRenderer() const memos = [ {id:1, text: 'testText1'}, {id:2, text: 'testText2'} ] renderer.render( <MemoList memos={ memos } /> ) const actual = renderer.getRenderOutput(); const expect = ( <ul className="memoList"> <li key="1">testText1</li> <li key="2">testText2</li> </ul> ) assert.deepEqual(actual, expect) assert.ok(true); }) it('AddMemo', function () { const renderer = createRenderer() let memo = 'before' // node.js で renderIntoDocument するには jsdom の力が必要 const component = ReactTestUtils.renderIntoDocument( <AddMemo handleMemoSubmit={() => { memo = 'after' }} /> ) assert.ok(memo === 'before', 'input.value is empty') const input = ReactTestUtils.findRenderedDOMComponentWithTag(component, 'input'); input.value = 'xxxx'; const form = ReactTestUtils.findRenderedDOMComponentWithTag(component, 'form'); ReactTestUtils.Simulate.submit(form) assert.ok(memo === 'after') }) })
実行
% NODE_ENV=test $(npm bin)/mocha --compilers js:babel-register
まとめ
前回 Memo アプリで redux
の部分となる actions, reducers を定義し、今回は react
の部分となる components を定義しました。