flowtype入門2
テスト編
テストもflowで書きたいという欲求
以下を加えてみた
- mocha: テストフレームワーク
- expect: アサーション用(mocha自体は提供しないので)
- expect-jsx: JSXアサーション
- react-addons-test-utils: Reactテスト用
- jsdom: Reactテスト時 (ReactTestUtils.renderIntoDocumentを動かす際にDOM実装が必要)
- jsdom-global: 面倒なjsdomの初期化とglobal.windowへの設定をやってくれる
- babel-register: テストコードもes2015で書けるように
npm test でテスト実行される
package.json
{ "name": "sample", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "browserify -o bundle.js -t babelify ./scripts/index.js", "start": "watchify -o bundle.js -t babelify ./scripts/index.js", "lint": "eslint scripts tests", "test": "mocha -r babel-register -r jsdom-global/register --recursive tests" }, "keywords": [], "author": "", "license": "MIT", "engines": { "node": ">=6.x", "npm": ">=3.x" }, "devDependencies": { "mocha": "^3.2.0", "expect": "^1.20.2", "expect-jsx": "^3.0.0", "react-addons-test-utils": "^15.4.2", "jsdom": "^9.9.1", "jsdom-global": "^2.1.1", "babel-register": "^6.18.0", "flow-bin": "^0.38.0", "babel-cli": "^6.18.0", "babel-plugin-transform-flow-strip-types": "^6.21.0", "babel-preset-es2015": "^6.18.0", "babel-preset-react": "^6.16.0", "babelify": "^7.3.0", "browserify": "^13.3.0", "watchify": "^3.8.0", "eslint": "^3.13.1", "babel-eslint": "^7.1.1", "eslint-plugin-react": "^6.9.0", "eslint-plugin-flowtype": "^2.30.0", "eslint-plugin-flowtype-errors": "^2.0.3" }, "dependencies": { "flux": "^3.1.2", "react": "^15.4.2", "react-dom": "^15.4.2" } }
サンプル
component.state.inputValue を component.state.inputValue2にしてflowコマンド動かすと怒られるようになる。
tests/test.js
// @flow import { describe, it } from 'mocha'; import assert from 'assert'; import Sample from '../scripts/Sample'; import React from 'react'; import ReactTestUtils, { createRenderer } from 'react-addons-test-utils'; import expect from 'expect'; import expectJSX from 'expect-jsx'; expect.extend(expectJSX); describe('Sample', () => { let renderer = createRenderer(); describe('render', () => { it('コンポーネントが動くこと', () => { renderer.render(<Sample />); let actualElement = renderer.getRenderOutput(); let expectedElement = ( <div className="sampleComponent"> bar </div> ); expect(actualElement).toEqualJSX(expectedElement); }); it('state', () => { let component: Sample = ReactTestUtils.renderIntoDocument(<Sample/>); expect(component.state.inputValue).toBe('foo'); }); }); });
scripts/Sample.jsx
// @flow import React from 'react'; type Props = {}; export default class Sample extends React.Component { props: Props; state: { inputValue: string }; constructor(props: Props) { super(props); this.state = { inputValue: 'foo' }; } render() { return ( <div className="sampleComponent"> bar </div> ); } }