reduxのドキュメントによると connected
コンポーネントは connect
対象のコンポーネントを export
してテストしましょう。と書いてあります。
が、どっちかというと mapStateToProps
や mapDispatchToProps
がどんな挙動になるかテストしたかったので、こちらの良さげな例を自分なりに少しアレンジしてみました。
import { shallow } from 'enzyme'
import { expect } from 'chai'
import React from 'react'
import configureStore from 'redux-mock-store'
import { connect } from 'react-redux'
// actionCreator
const changeName = value => ({ type: 'CHANGE_NAME', payload: value })
// statelessComponent
const Hello = props => {
return (
<div>
Hello {props.name}!!
<input onChange={props.onChange} value={props.name} />
</div>
)
}
// containerComponent
const mapStateToProps = state => {
return {
name: state.hello.name
}
}
const mapDispatchToProps = dispatch => {
return {
onChange: e => {
dispatch(changeName(e.target.value))
}
}
}
const Container = connect(mapStateToProps, mapDispatchToProps)(Hello)
// test
const shallowWithStore = (component, store) => {
const context = {
store
}
return shallow(component, { context })
}
describe('Container', () => {
const state = {
hello: {
name: 'foo'
}
}
const createMockStore = configureStore()
const store = createMockStore(state)
const wrapper = shallowWithStore(<Container />, store)
it('name', () => {
expect(wrapper.props().name).to.eql(state.hello.name)
})
it('onChange', () => {
wrapper.props().onChange({ target: { value: 'bar' } })
expect(store.getActions()).to.includes(changeName('bar'))
})
})
結局のところ何をテストしたいかというと、 state
が connect
対象のコンポーネントにどういう props
として渡されているかということと、props
として渡されたハンドラがどういうアクションを発行するかというところなので、 shallowWrapper.props()
の中身をテストしてやればいいということになります。
特にハンドラは今回シンプルに ActionCreator
を実行するだけのものですが、複雑な分岐がある場合でもただの副作用のない関数をテストするのと同じことなので簡単にテストが書けると思います。