如何使用 Jest 测试 Thunk 操作?

Posted

技术标签:

【中文标题】如何使用 Jest 测试 Thunk 操作?【英文标题】:How can I test Thunk actions with Jest? 【发布时间】:2017-12-18 07:12:45 【问题描述】:

我是使用 Jest 对 Redux-Thunk 异步操作进行单元测试的新手。

这是我的代码:

export const functionA = (a, b) => (dispatch) => 
    dispatch( type: CONSTANT_A, payload: a );
    dispatch( type: CONSTANT_B, payload: b );
 

如何使用 Jest 测试此功能?

【问题讨论】:

【参考方案1】:

Redux 文档中有一个示例:http://redux.js.org/docs/recipes/WritingTests.html#async-action-creators

import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
const middlewares = [thunk]
const mockStore = configureMockStore(middleware)

describe('async actions', () => 
    
  it('should dispatch actions of ConstantA and ConstantB', () => 
    const expectedActions = [
      type: CONSTANT_A, payload: 'a',
      type: CONSTANT_B, payload: 'b' 
    ]

    const store = mockStore( yourInitialState )
    store.dispatch(actions.functionA('a', 'b'))

    expect(store.getActions()).toEqual(expectedActions)
  )
)

【讨论】:

感谢@luanped 的回答,我试过了,但没用。问题是,我的功能不是 Promise :( 那就更简单了,我用一个例子更新了答案 好方法,说教!【参考方案2】:

我建议你写这样的东西来避免异步问题:

return store
  .dispatch(actionCreators.login())
  .then(() => expect(store.getActions()).toEqual(expectedActions));

【讨论】:

【参考方案3】:

另外,为了更方便,你可以使用这个模块:https://www.npmjs.com/package/redux-thunk-tester

例子:

import React from 'react';
import createStore, applyMiddleware, combineReducers from 'redux';
import reducer from './example';
import ReduxThunkTester from 'redux-thunk-tester';
import thunk from 'redux-thunk';

const request = (ms) => new Promise((resolve) => 
  setTimeout(() => resolve('success response'), ms);
);

const resultRequestAction = (value) => ( type: SOME_BACKEND_REQUEST, payload: value );
const toggleLoadingAction = (value) => ( type: TOGGLE_LOADING, payload: value );

const asyncThunkWithRequest = () => async (dispatch) => 
  try 
    dispatch(toggleLoadingAction(true));
    const result = await request(200);
    dispatch(resultRequestAction(result));
   finally 
    dispatch(toggleLoadingAction(false));
  
;

const createMockStore = () => 
  const reduxThunkTester = new ReduxThunkTester();

  const store = createStore(
    combineReducers(exampleSimple: reducer),
    applyMiddleware(
      reduxThunkTester.createReduxThunkHistoryMiddleware(),
      thunk
    ),
  );

  return reduxThunkTester, store;
;

describe('Simple example.', () => 
  test('Success request.', async () => 
    const store, reduxThunkTester: getActionHistoryAsync, getActionHistoryStringifyAsync = createMockStore();

    store.dispatch(asyncThunkWithRequest());

    const actionHistory = await getActionHistoryAsync(); // need to wait async thunk (all inner dispatch)

    expect(actionHistory).toEqual([
      type: 'TOGGLE_LOADING', payload: true,
      type: 'SOME_BACKEND_REQUEST', payload: 'success response',
      type: 'TOGGLE_LOADING', payload: false,
    ]);

    expect(store.getState().exampleSimple).toEqual(
      loading: false,
      result: 'success response'
    );

    console.log(await getActionHistoryStringifyAsync(withColor: true));
  );
);

【讨论】:

以上是关于如何使用 Jest 测试 Thunk 操作?的主要内容,如果未能解决你的问题,请参考以下文章

使用 React、Jest、Redux 和 Thunk 进行无限循环测试

jest redux-thunk 测试是不是调度了相同模块的操作

Jest test redux action with thunk 不包括 statemets

在未弹出 Redux 的情况下测试 Jest React-Native Expo CRNA

单元测试 react redux thunk dispatches with jest and react testing library for "v: 16.13.1",

如何使用 Jest 测试 Rxjs 空操作符