【问题标题】:React Redux async action testingReact Redux 异步操作测试
【发布时间】:2016-07-13 15:25:21
【问题描述】:

我编写了测试来测试异步操作。我目前收到以下错误TypeError: Cannot read poperty 'then' of undefined,它指向我的代码中的以下行

return store.dispatch(actions.fetchMovies()).then(() => {

这是我的代码:

异步操作测试:

import { createStore, applyMiddleware } from 'redux';
import initialState from '../reducers/initialState';
import rootReducer from '../reducers/index';
import thunk from 'redux-thunk';
import * as actions from './actions';
import * as ActionTypes from '../constants/constants';
import nock from 'nock';
import { expect } from 'chai';
import API_KEY from '../config/config';

const MOVIES_API = 'https://api.themoviedb.org/3/discover/movie?api_key='+API_KEY;

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

  it('creates FETCH_MOVIES_SUCCESS when fetching movies is complete', () => {
    nock(MOVIES_API)
      .get()
      .reply(200, {data: {results: [{title: 'Batman vs Superman'}]}});

    const expectedActions = [
      { type: ActionTypes.FETCH_MOVIES },
      { type: ActionTypes.FETCH_MOVIES_SUCCESS, data: {results: [{title: 'Batman vs Superman'}]}}
    ];

    const store = createStore(rootReducer, initialState, applyMiddleware(thunk));

    return store.dispatch(actions.fetchMovies()).then(() => {
        expect(store.getActions()).to.deep.equal(expectedActions);
      });
  });
});

行动:

import axios from 'axios';

import * as constants from '../constants/constants';
import API_KEY from '../config/config';


export const fetchMovies = () => {
  const MOVIES_API = 'https://api.themoviedb.org/3/discover/movie?api_key='+ API_KEY;

  return dispatch => {
    dispatch({
      type: constants.FETCH_MOVIES
    });
    axios.get(MOVIES_API).then(function(response) {
      dispatch({
        type: constants.FETCH_MOVIES_SUCCESS,
        data: response.data.results
      });
    })
    .catch(function(res) {
      dispatch({
        type: constants.FETCH_MOVIES_ERROR,
        msg: res.message
      });
    });
  };
};

这是第一次测试异步操作,所以我不确定出了什么问题。

【问题讨论】:

  • 只想提到 redux-saga yelouafi.github.io/redux-saga 作为处理异步操作流的一种方式。它的部分好处是您可以轻松测试异步操作的每个部分。

标签: javascript reactjs redux react-redux


【解决方案1】:

这是因为您的操作没有返回承诺 - 更改您的操作以返回可以等待的承诺。这不是必需的,但如果您想知道您的 API 调用何时完成(即您的单元测试想知道在这种特殊情况下),那么您可以返回一个承诺作为操作的便利副作用:

export const fetchMovies = () => {
  const MOVIES_API = 'https://api.themoviedb.org/3/discover/movie?api_key='+ API_KEY;

  return dispatch => {
    dispatch({
      type: constants.FETCH_MOVIES
    });

    // Return a promise
    return axios.get(MOVIES_API).then(function(response) {
      dispatch({
        type: constants.FETCH_MOVIES_SUCCESS,
        data: response.data.results
      });
    })
    .catch(function(res) {
      dispatch({
        type: constants.FETCH_MOVIES_ERROR,
        msg: res.message
      });
    });
  };
}

;

【讨论】:

    【解决方案2】:

    尝试使用redux-mock-store 而不是redux createStore()。这是一个用于测试异步操作创建者和中间件的模拟商店。 Github 页面还包含一些如何使用它的示例。

    编辑:

    当你修改你的动作创建者让它返回axios.get(MOVIES_API)的结果时会发生什么?

    【讨论】:

    • 我首先尝试使用 redux-mock-store,并且发生了同样的事情。这就是我转而只创建普通商店的原因,因为我在一个示例中也看到了这一点。而且我不应该改变动作返回的内容来使这项工作......这些动作工作正常
    • 我认为你应该试一试。当你的动作创建者没有返回承诺时,你不能链接另一个 then()
    • 重写了,测试开始了,现在报错Error: Nock: No match for request get https://api.themoviedb....
    • @erichardson30 你是怎么解决这个问题的?介意分享:)
    猜你喜欢
    • 2017-10-14
    • 2021-04-03
    • 2017-03-04
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    相关资源
    最近更新 更多