当promise在Redux中间件中解析时,为什么我不能调度操作?

时间:2017-01-06 19:57:29

标签: javascript node.js ecmascript-6 redux es6-promise

背景

我正在编写一个Redux中间件,它发出了一个axios请求,并使用Cheerio来解析结果。

问题

当Axios承诺结算并且我尝试调度已完成的操作时,该操作不会显示在测试中商店的操作日志中。

中间件

function createMiddleware() {
    return ({ dispatch, getState }) => next => action => {

      if (isCorrectAction(action)===true){

      const pendingAction = {
        type: `${action.type}_PENDING`,
        payload: action.payload
      }

      dispatch(pendingAction)

      axios.get(action.payload.url)
            .then(response => {
              let $ = cheerio.load(response.data)
              let parsedData = action.payload.task($)

              const fulfilledAction = {
                type: `${action.type}_FULFILLED`, 
                payload: { 
                  parsedData 
                }
              }

              dispatch(fulfilledAction) // dispatch that is problematic

            })
            .catch( err => {

            });
       }

        return next(action);
    }
}

测试已完成操作的调度失败

   it('should dispatch ACTION_FULFILLED once', () => {
       nock("http://www.example.com")
           .filteringPath(function(path) {
               return '/';
           })
           .get("/")
           .reply(200, '<!doctype html><html><body><div>text</div></body></html>');

       const expectedActionTypes = ['TASK', 'TASK_PENDING', 'TASK_FULFILLED']

       // Initialize mockstore with empty state
       const initialState = {}
       const store = mockStore(initialState)
       store.dispatch(defaultAction)

       const actionsTypes = store.getActions().map(e => e.type)
       expect(actionsTypes).has.members(expectedActionTypes);
       expect(actionsTypes.length).equal(3);
   });

1 个答案:

答案 0 :(得分:1)

解决方案 - 需要在mocha测试中返回Promise

解决方案是重写mocha测试,以便返回promise。我错误地认为通过使用nock拦截HTTP请求,promise将变为同步。

工作测试如下:

it('should dispatch ACTION_FULFILLED once', () => {
    nock("http://www.example.com")
        .filteringPath(function(path) {
            return '/';
        })
        .get("/")
        .reply(200, '<!doctype html><html><body><div>text</div></body></html>');

    const store = mockStore();

    return store.dispatch(defaultScrapingAction)
                .then(res => {   

         const actionsTypes = store.getActions().map(e => e.type)
         expect(actionsTypes).has.members(expectedActionTypes);
         expect(actionsTypes.length).equal(3);
    })
});