包含 axios GET 调用的 React-Redux 应用程序测试操作创建者

Posted

技术标签:

【中文标题】包含 axios GET 调用的 React-Redux 应用程序测试操作创建者【英文标题】:React-Redux app testing action creator containing axios GET call 【发布时间】:2018-01-21 03:34:02 【问题描述】:

我正在编写一个 react-redux 应用程序,并且在我的一个动作创建者中,我正在通过 axios 发出 api 请求

大概是这样的:

import axios from 'axios'


export function getStoredData(userInput) 
    .
    .
    .

    var url = generateURL(userInput);

    var response = axios.get(url);

    return 
        type: GET_STORED_DATA
        payload: repsonse;
    ;

我想mock axios 使用 axios-mock-adapter 但我不太明白该怎么做,尤其是因为我不想为测试修改我的action creator

请建议任何资源/指南来执行此操作...

【问题讨论】:

注入你的http客户端(在这种情况下)axios作为依赖。有了它,您可以轻松地将其交换为模拟实现以进行测试。 @jimmyweb ^我仍然不清楚这是如何工作的...... 【参考方案1】:

您可以使用依赖注入来交换http客户端,例如。

// your api module
var httpClient

export function getStoredData(userInput) 
    .
    .
    .

    var url = generateURL(userInput);

    var response = httpClient.get(url);

    return 
        type: GET_STORED_DATA
        payload: repsonse;
    ;


export default function init(client) 
    httpClient = client


// init it when your program starts and the use it (should be a singleton instance in the app)
import Api,  getStoredData  from './api'
import axios from 'axios'
Api.init(axios)
getStoredData('user input')

//in your test
import Api,  getStoredData  from './api'
import axiosMock from 'axios-mock-adapter'
Api.init(axiosMock)

【讨论】:

【参考方案2】:
import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import moxios from 'moxios';
import 
  submitRegistrationStepOneForm, // <-- this is an action that returns returns a promise
 from '../RegistrationActions';

const USER_ID = 999;
const USER_EMAIL = 'lucky_star@milkyway.test';
const userDataForStepOne =  email: USER_EMAIL ;
const responseForUserRequest =  content:  id: USER_ID  ;
const middlewares = [thunk];

const mockStore = configureStore(middlewares);

describe('Registration action tests for form', () => 
  beforeEach(() => moxios.install());
  afterEach(() => moxios.uninstall());

  it('submitRegistrationStepOneForm success should trigger correct dispatches', () => 
    const initialState = ;
    const store = mockStore(initialState);

    // simplest way is to use a regex to match url
    moxios.stubRequest(/users.*/, 
      status: 201,  // <-- you can replace this with a 5xx to test failure cases
      response: responseForUserRequest,
    );

    return store.dispatch(submitRegistrationStepOneForm(
      userData: userDataForStepOne,
    ))
      .then(() => 
        // in my case I used to run 2 dispatches on success call: 
        const actions = store.getActions();
        expect(actions.length).toEqual(2);
        expect(actions[0]).toEqual( type: 'SUBMIT_REGISTRATION_FORM_DATA' );
        expect(actions[1]).toEqual(
          type: 'SUBMIT_REGISTRATION_STEP_ONE_SUCCESS',
          payload:  userId: USER_ID ,
        );
        // ... more tests here if needed
      );
  );
  // ....

submitRegistrationStepOneForm 操作:

export const submitRegistrationStepOneForm = ( userData, sourceArticle ) => 
  return (dispatch) => 
    dispatch(submitRegistrationDataAction());
    // signUpStepOne can be replaced directly with the axios promise
    return signUpStepOne( userData )
      .then((body) => 
        const  content:  id   = body;
        // ... some function calls and 2 dispatches here like:
        // dispatch(registrationSuccess( userId: id ));
      )
      .catch((error) => 
        console.log('step one error', error); // eslint-disable-line
        dispatch(registrationFailureAction());
      );
  ;
;

【讨论】:

以上是关于包含 axios GET 调用的 React-Redux 应用程序测试操作创建者的主要内容,如果未能解决你的问题,请参考以下文章

从 Axios API 返回数据

axios调用api用GET变成OPTIONS

进行 axios.get 调用时出现 CORS 错误

调用 axios.get() 时无法获取 /[object%20Object]

Axios POST 调用不适用于 JWT 令牌,而 GET 调用有效

如何从我得到的数组中获取特定的数组元素作为调用 axios.get() 调用的函数的响应 [重复]