React 0.14 mocha组件单元测试(二)
使用react的情况下,一般也会用到redux,那么对于这种在react中使用redux的情况,写测试的时候就不能只用之前的文章里面介绍的方式写了。
来看下组件例子
import React, { Component, findDOMNode } from 'react' import { connect } from 'react-redux' import { increase, decrease, fetchItems } from '../../actions/counter' class Home extends Component { render() { const { item, number, isFetching, increase, decrease, fetchItems } = this.props; return ( <div className='container'> <div className='row'> Some state changes: {number} <p>Item Length : {item.length}</p> <p>Request Item State:{!isFetching ? '已完成' : '获取中'}</p> </div> <div className='btn-group'> <button className='btn btn-primary btn-xs' onClick={() => increase(1)}>Increase</button> <button className='btn btn-primary btn-xs' onClick={() => decrease(1)}>Decrease</button> <button className='btn btn-primary btn-xs' onClick={() => fetchItems(item)}>FetchItems</button> </div> </div> ) } componentDidMount() { // const { item, fetchItems } = this.props; // fetchItems(item) } componentDidUpdate() { console.log('did update'); } } export default connect( state => { const { counter } = state; return { number: counter.number, item: counter.item || [], isFetching: counter.isFetching || false } }, { increase, decrease, fetchItems } )(Home)
这里涉及到了actions,那么代码如下:
import { INCREASE, DECREASE, REQUEST_DATA, FETCH_DATA, RECEIVE_DATA, ERROR_DATA } from '../constants'; import Utils from 'utils'; import $ from 'jquery'; const token = Utils.get_token(); require('babel-polyfill'); export function increase(n) { return { type: INCREASE, amount: n } } export function decrease(n) { return { type: DECREASE, amount: n } } export function fetchData(item) { return dispatch => { return new Promise((resolve, reject) => { let sql = `SELECT * FROM qeeniao.user limit 0,10`; $.ajax({ url: '/proxy/admin/query', dataType: 'json', type: 'post', data: { access_token: token, sql: sql }, beforeSend: () => { resolve(dispatch(requestData(item))); }, success: (data) => { resolve(dispatch(receiveData(item, data))); }, error: (error) => { console.log(error.message); reject(dispatch(errorData(item, error))); } }) }); } } function errorData(item, error) { return { type: ERROR_DATA, item: item || [], error: error } } function requestData(item) { return { type: REQUEST_DATA, item: item || [] } } function receiveData(item, data) { return { type: RECEIVE_DATA, item: (item || []).concat(data), data: data } } export function fetchItems(item = []) { return (dispatch, getState) => { return dispatch(fetchData(item)) } }
这里又涉及到了contants,代码如下
export const INCREASE = 'INCREASE' export const DECREASE = 'DECREASE' export const FETCH_DATA = 'FETCH_DATA'; export const RECEIVE_DATA = 'RECEIVE_DATA'; export const REQUEST_DATA = 'REQUEST_DATA'; export const ERROR_DATA = 'ERROR_DATA';
到这里基本上一个简单的例子就出来了。让我们写个测试吧。
import React from 'react'; import expect from 'expect'; import { counter } from '../../app/js/reducers'; import TestUtils from 'react-addons-test-utils'; import Home from '../../app/js/components/test/Home'; import { Provider } from 'react-redux'; import { createStore, combineReducers } from 'redux'; const reducer = combineReducers({ counter }) const configureStore = (initialState) => { const store = createStore(reducer, initialState); return store; } describe('Home components', () => { before('render and locate element ', function(){ const store = configureStore({}); const renderedComponent = TestUtils.renderIntoDocument( <Provider store={store}> <Home /> </Provider> ); const container = TestUtils.findRenderedDOMComponentWithClass( renderedComponent, 'container' ); const row = TestUtils.findRenderedDOMComponentWithClass( renderedComponent, 'row' ); const btnGroup = TestUtils.findRenderedDOMComponentWithClass( renderedComponent, 'btn-group' ) this.container = container; this.row = row; this.btnGroup = btnGroup; }); it('container should exist', function(){ expect(this.container).toExist(); }); it('container class name should be container', function(){ expect(this.container.getAttribute('class')).toBe('container'); }); it('row should exist', function() { expect(this.row).toExist(); }); it('row class name should be row', function() { expect(this.row.getAttribute('class')).toBe('row'); }); it('btnGroup should exist', function(){ expect(this.btnGroup).toExist(); }) it('btnGroup class name should be btn-group', function() { expect(this.btnGroup.getAttribute('class')).toBe('btn-group'); }); })
我去,又牵扯到了reducers了,代码如下:
这里说下,我是把reducer做了一个目录的方式来调用。
reducers
--couner.js
--index.js
index.js的代码如下:
import counter from './counter' export { counter } ;
counter.js的代码如下:
import { INCREASE, DECREASE, REQUEST_DATA, FETCH_DATA, RECEIVE_DATA, ERROR_DATA } from '../constants'; const initialState = { number: 1 } export default function counter(state = initialState, action) { switch (action.type) { case INCREASE: return { number: state.number + action.amount, item: state.item || [] } break; case DECREASE: return { number: state.number - action.amount, item: state.item || [] } break; case REQUEST_DATA: return { number: state.number, isFetching: true, item: action.item || [] } break; case FETCH_DATA: return { number: state.number, isFetching: true, item: action.item || [] } break; case ERROR_DATA: return { number: state.number, isFetching: false, item: action.item || [], error: action.error } break; case RECEIVE_DATA: return { number: state.number, isFetching: false, item: action.item || [], data: action.data } break; default: return state; } }
好了,到这里,相关的一些配置可以在浏览下这篇文章:React 0.14 mocha组件单元测试(一)。
版权声明
由 durban创作并维护的 Gowhich博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证。
本文首发于 博客( https://www.gowhich.com ),版权所有,侵权必究。
本文永久链接: https://www.gowhich.com/blog/735
版权声明
由 durban创作并维护的 Gowhich博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证。
本文首发于 Gowhich博客( https://www.gowhich.com ),版权所有,侵权必究。
本文永久链接: https://www.gowhich.com/blog/735