状态测试

在 React App 的开发过程中,我们将状态测试主要分为 Action Test、Reducer Test 和 Selector Test。

Action Test

同步 action

sync action 的单元测试相对比较简单,主要测试 action creator 的返回值是否正确,示例代码:

describe('#action# setDiscountType', () => {
    const lineId = '456adc81-7b5a-4863-95b1-b43d1539a233';
    const discountType = 0;
    it('should return setDiscountType action creator correctly', () => {
        const action = setDiscountType(lineId, discountType);
        expect(action).to.have.property('type', actionTypes.LINES_SET_REQUEST);
        expect(action).to.have.property('lineId', lineId);
        expect(action).to.have.property('discountType', discountType);
    });
}

异步 action

async action 的单元测试相对比较复杂,结合项目中的 redux-thunk 进行测试,主要测试异步 action 中的REQUEST、SUCCESS、ERROR 在不同情况下是否按照预期进行调用,示例代码:

describe('#action# setLinesData', () => {
    const dispatch = jest.fn();
    const lineId = '456adc81-7b5a-4863-95b1-b43d1539a233';
    const lineData = {...};
    const getState = jest.fn().mockReturnValue(Immutable({...}));

    afterEach(jest.clearAllMocks);

    it('should set lines data success', done => {
        const utils = {
            ProformaService: {
                setLinesData: jest.fn().mockReturnValue(Promise.resolve())
            }
        };
        setLinesData(lineId, false, lineData)(dispatch, getState, utils)
            .then(() => {
                expect(dispatch).toHaveBeenCalledWith({
                    type: actionTypes.LINES_SET_REQUEST
                });
                expect(dispatch).toHaveBeenCalledWith({
                    type: actionTypes.LINES_SET_SUCCESS
                });
                done();
            })
            .catch(done.fail);
    });
}

函数中的业务逻辑,需要根据具体的情况进行测试。

Reducer Test

reducer 的测试一般是期望 reducer(state, action) === newState,其实这种方式和 (input) => output 的模式是一样的。

测试 state 首先要引入 Immutable 保证状态树的不可变性,示例代码:

import Immutable from 'seamless-immutable';

const initialState = Immutable({...});
const action = { type: ..., payload: ...};
const expectedState = {...};

expect(reducer(initialState, action)).toEqual(expectedState);

Selector Test

Selector Test 其实也是 (input) => output 这种模式,同样测试的时候也要引入 Immutable 来保证状态树的不可变性,示例代码:

import Immutable from 'seamless-immutable';

const state = Immutable({...});
const expectedprops = {...};

expect(selector.getLines(state)).toEqual(expectedprops);

Last updated