【问题标题】:React Jest test actions that do fetch to APIReact Jest 测试获取 API 的操作
【发布时间】:2020-03-30 16:36:01
【问题描述】:

我正在尝试为执行获取的操作连接测试。到远程 API。

到目前为止,我只看到了 Jest 测试操作的示例,这些操作不执行任何获取,而是将操作分派给减速器。

我将如何测试一个确实获取 API 的操作(在本例中,这是一个节点服务器),但节点将无法用于运行测试。我想需要做的是模拟这个。我该怎么办?如何模拟 fetch?

import { VEHICLE } from './types';
import { API_ADDRESS } from '../config';


const fetchVehicle = ({ endpoint, options, SUCCESS_TYPE }) => (dispatch) => {
  dispatch({ type: VEHICLE.FETCH });
  return fetch(`${API_ADDRESS}/vehicle/${endpoint}`, options)
        .then(response => response.json())
        .then(json => {
          if (json.errors !== undefined) {
            dispatch({ type: VEHICLE.FETCH_ERROR, ...json });
          } else {
            // console.log('action', {...json})
            dispatch({ type: SUCCESS_TYPE, ...json });
          }
        })
        .catch(error => dispatch({
          type: VEHICLE.FETCH_ERROR, errors: [{ msg: error }]
        }));
}


export const fetchAllVehicles = ({ limit, skip }) => fetchVehicle({
  endpoint: '?limit=' + limit + '&skip=' + skip,
  options: { credentials: 'include' },
  SUCCESS_TYPE: VEHICLE.FETCH_ALL_SUCCESS
});


export const fetchVehicleId = ({ id }) => fetchVehicle({
  endpoint: `${id}`,
  options: { credentials: 'include' },
  SUCCESS_TYPE: VEHICLE.FETCH_ID_SUCCESS
});


export const deleteVehicleId = ({ id }) => fetchVehicle({
  endpoint: `${id}`,
  options: {
    method: 'DELETE',
    options: { credentials: 'include' },
  },
  SUCCESS_TYPE: VEHICLE.FETCH_DELETE_SUCCESS
});


export const addNewVehicle = ({ vehicle }) => fetchVehicle({
  endpoint: '',
  options: {
    method: 'POST',
    body: JSON.stringify({ ...vehicle }),
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include'
  },
  SUCCESS_TYPE: VEHICLE.FETCH_ADD_SUCCESS
});


export const updateVehicle = ({ vehicle }) => fetchVehicle({
  endpoint: `${vehicle.id}`,
  options: {
    method: 'PUT',
    body: JSON.stringify({ ...vehicle }),
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include'
  },
  SUCCESS_TYPE: VEHICLE.FETCH_UPDATE_SUCCESS
});


export const fetchAllLockedVehicles = ({ limit, skip }) => fetchVehicle({
  endpoint: 'locked/?limit=' + limit + '&skip=' + skip,
  options: { credentials: 'include' },
  SUCCESS_TYPE: VEHICLE.FETCH_LOCKED_SUCCESS
});


export const unlockVehicleId = ({ id }) => fetchVehicle({
  endpoint: `unlock/${id}`,
  options: {
    method: 'POST',
    options: { credentials: 'include' },
  },
  SUCCESS_TYPE: VEHICLE.FETCH_UNLOCK_SUCCESS
});


export const fetchVehiclesSearch = ({ search, limit, skip }) => fetchVehicle({
  endpoint: 'search/?search=' + search + '&limit=' + limit + '&skip=' + skip,
  options: { credentials: 'include' },
  SUCCESS_TYPE: VEHICLE.FETCH_SEARCH_SUCCESS
});


export const fetchLockedVehiclesSearch = ({ search, limit, skip }) => fetchVehicle({
  endpoint: '/locked/search/?search=' + search + '&limit=' + limit + '&skip=' + skip,
  options: { credentials: 'include' },
  SUCCESS_TYPE: VEHICLE.FETCH_LOCKED_SEARCH_SUCCESS
});


export const pushVehicleMessage = ({ type, status, message, fields }) => dispatch => {
  dispatch({ 
    type, 
    status,
    message,
    fields
  });
}


export const resetVehicle = () => dispatch => { 
  dispatch({ type: VEHICLE.RESET, status: 'success' }); 
}

【问题讨论】:

    标签: reactjs jestjs


    【解决方案1】:

    如您所料,理想的测试会模拟请求,以便您的测试受到控制并始终以相同的方式运行。

    此外,您必须考虑到,当您的代码发出 ajax 请求(本质上是异步操作)时,您必须将测试声明为异步(您可以阅读有关异步测试的更多信息 @987654321 @)。

    例如,您可以通过以下方式测试 fetchAllVehicles 动作创建者的成功案例:

    it('should get all vehicles', async () => {
        // Mock the global fetch call, returning a promise with a json method and the response data
        global.fetch = jest.fn().mockResolvedValue({
            json: () => ({ data: ['vehicle1', 'vehicle2'] })
        });
    
        // Mock the dispatch method in order to be able to make assertions
        const dispatch = jest.fn();
    
        // Call the action creator with the values.
        await fetchAllVehicles({
            limit: 10,
            skip: 2
        })(dispatch);
    
        // Assert that the dispatch method was called with the correct values.
        expect(dispatch).toHaveBeenCalledTimes(2);
        expect(dispatch).toHaveBeenCalledWith({
            type: VEHICLE.FETCH
        });
        expect(dispatch).toHaveBeenCalledWith({
            type: VEHICLE.FETCH_ALL_SUCCESS,
            data: ['vehicle1', 'vehicle2']
        });
    });
    

    【讨论】:

      猜你喜欢
      • 2018-07-05
      • 1970-01-01
      • 2021-08-25
      • 1970-01-01
      • 2021-10-16
      • 2019-03-22
      • 1970-01-01
      • 1970-01-01
      • 2020-10-26
      相关资源
      最近更新 更多