LoginSignup
60
59

More than 5 years have passed since last update.

JSDOMとReact.addons.TestUtilsでReactをヘッドレスにテストする

Last updated at Posted at 2015-03-14

JSDOMはnode環境でDOMをシミュレートするやつ。React.addons.TestUtilsはReactに同梱されているテストツール。この2つがあわさり最強に見える。

今作ってるライブラリのために、しばらくブラウザ使わずにテストしてたけど、ブラウザ立ち上げる必要なくて非常に快適。これ https://github.com/mizchi/arda/tree/master/test

JSDOM、昔はとにかく不安定な印象だったけど、最近はよくできてる印象。見なおした。

コード

# globalにdocumentとwindowを定義することで、DOM環境を参照できるようにする
# 必ずReactの前に読み込むこと
jsdom = require('jsdom').jsdom
global.document  = jsdom('<html><body></body></html>')
# global.window    = document.parentWindow # 追記 jsdom v4.0で parentWindow -> defaultView
global.window    = document.defaultView
global.navigator = window.navigator

# TestUtilsを使うためにreact/addonsを読み込む
React = require 'react/addons'

# 0.13.0-beta.1 以降で使える ES6 Class記法
# ※ 別にReact.createClassでも良いがgetInitialStateになる
class HelloComponent extends React.Component
  constructor: ->
    super
    @state = cnt: 0

  render: ->
    React.createElement 'button',
      className: 'counter'
      ref: 'counter'
      onClick: @onClick.bind(@)
    , 'cnt:'+@state.cnt

  onClick: ->
    @setState cnt: @state.cnt+1

# アサーション
assert = require 'assert'

# renderIntoDocumentはDOMにマウントせずcomponentを生成する
# ただしDOM環境は必要
component = React.addons.TestUtils.renderIntoDocument React.createFactory(HelloComponent)()

assert.equal component.refs.counter.getDOMNode().innerHTML, 'cnt:0'

# クリックをシミュレート
React.addons.TestUtils.Simulate.click component.refs.counter.getDOMNode()

# 再レンダーされているか確認
assert.equal component.refs.counter.getDOMNode().innerHTML, 'cnt:1'

# もう二回ぐらい叩いてみる
React.addons.TestUtils.Simulate.click component.refs.counter.getDOMNode()
React.addons.TestUtils.Simulate.click component.refs.counter.getDOMNode()
# 確認
assert.equal component.refs.counter.getDOMNode().innerHTML, 'cnt:3'

実はちょっと前まで動かなったけど、最近動くようになった。

ReactTestUtils.Simulate.click does not work with jsdom · Issue #1185 · facebook/react https://github.com/facebook/react/issues/1185

懸念点

jsdom v3.3.1 がまだ io.js v1.1.0でビルドできないので node v0.10を使った。jsdomの初期化、ちょっとだけ時間かかって、テストの実行のたびに0.6秒ぐらい必要。まあPhantomよりは遥かにマシ。

参考

60
59
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
60
59