0

我正在为一些异步操作编写测试,但是测试失败了,因为type返回的总是REQUEST_PENDING. 因此,即使对于获取数据时的测试,类型也不会改变并且测试失败。我不确定我做错了什么。

所以REQUEST_SUCCESSandREQUEST_FAILED是总是返回的测试REQUEST_PENDING

这是我的actions.js

import axios from 'axios';
import {
  REQUEST_PENDING,
  REQUEST_SUCCESS,
  REQUEST_FAILED,
} from './constants';

export const setSearchField = (payload) => ({ type: SEARCH_EVENT, payload });

export const requestRobots = () => {
  return async (dispatch) => {
    dispatch({
      type: REQUEST_PENDING,
    });
    try {
      const result = await axios.get('//jsonplaceholder.typicode.com/users');
      dispatch({ type: REQUEST_SUCCESS, payload: result.data });
    } catch (error) {
      dispatch({ type: REQUEST_FAILED, payload: error });
    }
  };
};

这是我的actions.test.js

import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import {
  REQUEST_PENDING,
  REQUEST_SUCCESS,
  REQUEST_FAILED,
} from './constants';
import * as actions from './actions';

const mock = new MockAdapter(axios);
const mockStore = configureMockStore([thunk]);
const payload = [
  {
    id: 1,
    name: 'robocop',
    email: 'robocop@gmail.com',
    key: 1,
  },
];


describe('handles requestRobots', () => {
  beforeEach(() => {
    // Runs before each test in the suite
    store.clearActions();
  });

  const store = mockStore();
  store.dispatch(actions.requestRobots());
  const action = store.getActions();

  it('Should return REQUEST_PENDING action', () => {
    expect(action[0]).toEqual({
      type: REQUEST_PENDING,
    });
  });


  it('Should return REQUEST_SUCCESS action', () => {
    mock.onGet('//jsonplaceholder.typicode.com/users').reply(200, {
      data: payload,
    });


    return store.dispatch(actions.requestRobots()).then(() => {
      const expectedActions = [
        {
          type: REQUEST_SUCCESS,
          payload: {
            data: payload,
          },
        },
      ];
      expect(store.getActions()).toEqual(expectedActions);
    });
  });

  it('Should return REQUEST_FAILURE action', () => {
    mock.onGet('//jsonplaceholder.typicod.com/users').reply(400, {
      data: payload,
    });


    return store.dispatch(actions.requestRobots()).then(() => {
      const expectedActions = [
        {
          type: REQUEST_FAILED,
          payload: {
            data: ['Error: Request failed with status code 404'],
          },
        },
      ];
      expect(store.getActions()).toEqual(expectedActions);
    });
  });
});
4

1 回答 1

1

thunk 动作的生命周期是它会REQUEST_PENDING在每次调用开始时分派动作,然后在结束时分派一个REQUEST_FAILEDREQUEST_SUCCESS动作。

在您的第二个和第三个测试用例中,store.getActions()数组实际上有两个元素:待处理操作和结果操作。您需要expect这些操作是一个包含两者的数组。和动作在那里REQUEST_FAILEDREQUEST_SUCCESS但你没有看到它们,因为它们是第二个元素。

将 your 定义pendingAction为变量,因为在所有三个测试中都需要它。

const pendingAction = {
  type: REQUEST_PENDING
}

然后将其包含在您的expectedActions数组中。

const expectedActions = [
  pendingAction,
    {
      type: REQUEST_SUCCESS,
      payload: {
        data: payload
      }
    }
]

这将使您的成功测试通过。我快速运行了测试,但失败测试仍然失败,因为它没有正确模拟 API 失败。现在它正在返回成功,因为该requestRobots函数使用真正的 axios 对象而不是模拟 axios 适配器。但也许你的环境中的某些东西以不同的方式处理这个问题。

于 2021-02-23T21:19:03.777 回答