无法在Redux中测试异步操作

时间:2016-04-14 16:33:28

标签: javascript unit-testing reactjs mocha redux

我正在尝试测试我的一个函数,该函数在redux中调用了我的应用程序。 测试是使用mocha,phantomjs。我正在使用nock来进行http调用。

我的测试是:

import React from 'react/addons';
import thunk from 'redux-thunk'
import nock from 'nock'
import expect from 'expect'
import configureMockStore from 'redux-mock-store'
import {RECEIVE_DATA1,RECEIVE_DATA2,RECEIVE_DATA3,fetchAllData} from '../../src/actions/allActions'


const middlewares = [ thunk ];
const mockStore = configureMockStore(middlewares);


  describe('async actions', () => {
    afterEach(() => {
      nock.cleanAll()
    })

    it('creates fetchAllDataAction call', (done) => {
      const requesting = false;
      nock('http://localhost:7788/')
        .get('/data/Data1')
        .reply(200,{ objects: { name: 'Test1'} } )
        .get('/Data2')
        .reply(200,{ objects: { name: 'Test2'} })
        .get('/Data3')
        .reply(200,{ objects: { name: 'Test3'} });

      const expectedActions = [
        { type: RECEIVE_DATA1 , objects: { name: 'Test1'}},
        { type: RECEIVE_DATA2 , objects: { name: 'Test2'}},
        { type: RECEIVE_DATA3 , objects: { name: 'Test3'} },
        { type: REQUEST_DATA3 , requesting},
      ]

      const store_mock = mockStore({},expectedActions,done)
      return store_mock.dispatch(fetchAllData())
        .then(() => {
          const actions = store.getActions()
          expect(actions).toEqual(expectedActions)
          done()
        })
    })
  })

我正在尝试测试此操作:

export function fetchAllData(){
  return dispatch => {
    return $.getJSON(`${SERVER_ROOT}/data/Data1`)
     .then(json => {
     dispatch(receiveData1(json));
     $.getJSON(`${SERVER_ROOT}/Data2`)
      .then(json => {
        dispatch(receiveData2(json));
        $.getJSON(`${SERVER_ROOT}/Data3`)
          .then(json => {
            dispatch(receiveData3(json));
            dispatch(requestData3(false));
          });
      });
  });
 }
}

function receiveData1(data){
 return { type: RECEIVE_DATA1,
          data: data
        }
}

function receiveData2(data){
 return { type: RECEIVE_DATA2,
          data
        }
}

function receiveData3(data){
 return { type: RECEIVE_DATA3,
          data
        }
 }

function requestData3(state){
 return { type: REQUEST_DATA3,
          state
        }
}

我收到以下错误: 超过2000ms超时。确保在此测试中调用done()回调。

我假设这可能是因为调度电话失败。 所以我改变了我的电话

   store_mock.dispatch(fetchAllData())
        .then(() => { // return of async actions
          expect(store_mock.getActions()).toEqual(expectedActions)
        })
        .then(done) 
        .catch(done)

我收到了这个错误:undefined不是构造函数(接近' .... catch(已完成); ...')

我不确定我在做什么错。我指的是http://redux.js.org/docs/recipes/WritingTests.html Async Action Creators教程。

我对前端测试很新。如果有人可以帮我解决这个问题会很棒。

提前感谢您的时间和帮助。

2 个答案:

答案 0 :(得分:0)

只需从done的参数和返回的promise的末尾删除it。当您测试承诺时,您应该只返回一个承诺而不进行任何done()回调

答案 1 :(得分:0)

您可以在mocha测试中简单地从it块返回一个承诺。这样您就可以避免添加不必要的thencatch块。

使用redux-actions-assertions

测试异步动作创建器也可能更容易

然后它将是简单的:

it('creates fetchAllDataAction call', () => {
  const requesting = false;
  nock('http://localhost:7788/')
    .get('/data/Data1')
    .reply(200,{ objects: { name: 'Test1'} } )
    .get('/Data2')
    .reply(200,{ objects: { name: 'Test2'} })
    .get('/Data3')
    .reply(200,{ objects: { name: 'Test3'} });

  const expectedActions = [
    { type: RECEIVE_DATA1 , objects: { name: 'Test1'}},
    { type: RECEIVE_DATA2 , objects: { name: 'Test2'}},
    { type: RECEIVE_DATA3 , objects: { name: 'Test3'} },
    { type: REQUEST_DATA3 , requesting},
  ]

  return expect(fetchAllData()).toDispatchActions(expectedActions)
})

甚至:

it('creates fetchAllDataAction call', () => {
  const requesting = false;
  const response1 = { objects: { name: 'Test1'}};
  const response2 = { objects: { name: 'Test2'}};
  const response3 = { objects: { name: 'Test3'}};

  nock('http://localhost:7788/')
    .get('/data/Data1')
    .reply(200, response1)
    .get('/Data2')
    .reply(200, response2)
    .get('/Data3')
    .reply(200, response3);

  return expect(fetchAllData()).toDispatchActions([
    receiveData1(response1),
    receiveData2(response2),
    receiveData3(response3),
    requestData3(requesting)
  ])
})