react-redux单元测试

by: kelen / 2016-11-25

Redux是什么?

Redux是JavaScript应用程序可预测状态的容器。工作流程图如如下

  1. 状态树通过 props 定义UI和action回调
  2. 用户在ui界面操作,例如点击事件,通过action creator来接收做相应的处理
  3. action 通过 reducer 来处理,实现逻辑代码,更新 state,存储
  4. 根据存储的新的state树更新 UI

在整个过程中,有三个需要实现的:component,actions,reducers

component 主要实现界面,触发相应的操作(点击,input改变等事件)

actions 对前端接受的操作动作分发给reducer做相应的处理

reducer 更新state,返回新的state

所以在写代码的期间,对上述三部分做单元测试,有利于错误的尽早定位和排除,加快开发速度。

测试工具react-scripts

react-scripts集成了babel(支持es6),webpack,autopreixer,eslint,jest等工具。

components 的测试选择官方的测试工具 react-addons-test-utils 最好不过了

安装react-addons-test-utils和react-scripts

npm install react-addons-test-utils react-scripts --save-dev

component单元测试

// src/components/UserCenter.js

import React, { PropTypes, Component } from 'react';

export default class UserCenter extends Component {

    static propTypes = {
        // 必须有, 显示更多函数
        user: PropTypes.object.isRequired,
        showMore: PropTypes.func.isRequired,
        isShowing: PropTypes.bool.isRequired
    }

    state = {
        showMore: false
    }

    showMore = (user) => {
        console.log(user);
        this.setState({ state: true });
    }

    render() {

        const { showMore } = this.props;

        return (
            <div className="user-center" onClick={(user) => showMore(user.id) }>
                <button>展开更多</button>
            </div>
        )
    }
}

对应的测试文件

// src/components/UserCenter.spec.js

import React from 'react';
import TestUtil from 'react-addons-test-utils';
import UserCenter from './UserCenter';

const setup = propOverried => {
    const props = Object.assign({
        user: {},
        showMore: jest.fn(),
        isShowing: false
    }, propOverried);

    const renderer = TestUtil.createRenderer();
    renderer.render(<UserCenter {...props}/>);

    const output = renderer.getRenderOutput();
    return {
        props: props,
        renderer: renderer,
        output: output
    }
}

describe('UserCenter组件测试', () => {
    it('渲染成功',() => {
        const { output } = setup();
        expect(output.type).toBe('div');
        expect(output.props.className).toBe('user-center');

        const button = output.props.children;
        expect(button.type).toBe('button');
    })
    it('触发showMore事件', () => {
        const { output, props } = setup();
        output.props.onClick({
            id: 12
        });
        expect(props.showMore).toBeCalled();
    })

})

action单元测试

// src/actions/UserActins.js

import * as UserActionTypes from '../constants/UserActionTypes';

// 添加用户
export const addUser = (user) => ({ type: UserActionTypes.ADD_USER, user });

对应的测试文件

// src/actions/UserActions.spec.js

import React from 'react';
import * as UserActions from './UserActions';
import * as UserActionTypes from '../constants/UserActionTypes';

describe('userActions', () => {
    it ('添加用户', () => {
        expect(UserActions.addUser({
            name: "kelen",
            age: 25
        })).toEqual({
            type: UserActionTypes.ADD_USER,
            user: {
                name: "kelen",
                age: 25
            }
        })
    })
})

reduces单元测试

// src/reducers/UserReducers.js

import * as UserActionTypes  from '../constants/UserActionTypes';

const initialState = []

export default function UserReducers (state = initialState, action) {
    switch (action.type) {
        case UserActionTypes.ADD_USER:
            return [
                {
                    id: 1,
                    user: action['user']
                },
                ...state
            ]
        default:
            return state;
    }
}

对应的测试文件

// src/reducers/UserReducers.spec.js

import * as UserActionTypes from '../constants/UserActionTypes';
import UserReducers from './UserReducers';

describe('UserReducers', () => {
    it ('返回初始化空数组', () => {
        expect(UserReducers(undefined, {})).toEqual([]);
    });

    it ('新增用户', () => {
        expect(UserReducers([], {
            type: UserActionTypes,
            user: {
                name: 'kobe',
                age: 35
            }

        }.ADD_USER)).toEqual([
            {
                id: 1,
                user: {
                    name: 'kobe',
                    age: 35
                }
            }
        ])
    })
})

测试方法

主需要在项目根目录下,执行命令,就会自动执行测试文件了,以后每次编辑文件会自动执行测试

react-scripts test

执行结果如下图:

参考资料:

react组件测试工具:Test Utilities

jest测试工具:Jest


最新发布
热门文章