使用多个调度(加载,错误和成功)测试动作

时间:2019-11-18 11:28:34

标签: reactjs jestjs redux-thunk

我如何为具有多个调度(正在加载,错误和成功)的动作创建测试,让我们看看我的动作之一:

import axios from 'axios';
import { CompaniesActionTypes } from './types';

export const getCompanies = () => async (dispatch: any) => {
    dispatch({
        type: CompaniesActionTypes.LOADING
    })
    try {
        const response = await axios.get('app/admin/companies');
        dispatch({
            type: CompaniesActionTypes.GET_COMPANIES,
            payload: response.data
        })
    } catch (error) {
        console.log(error.message);
        dispatch({
            type: CompaniesActionTypes.ERROR,
            payload: 'There was an error while requesting list of companies, please try again later.'
        })
    }
}

要了解更多信息,以下是我针对这种情况的减速器

import { CompaniesActionTypes, CompaniesState } from './types';
import { Reducer } from 'redux';

const INITIAL_STATE: CompaniesState = {
    data: [],
    loading: false, 
    error: ''
}

export const reducer: Reducer<CompaniesState> = (state = INITIAL_STATE, action) => {
    switch (action.type) {
        case CompaniesActionTypes.GET_COMPANIES:
            return {...state, data: action.payload, loading: false, error: ''}
        case CompaniesActionTypes.LOADING: 
            return {...state, loading: true};
        case CompaniesActionTypes.ERROR:
            return {...state, error: action.payload, loading: false};
        default:
            return state
    }
}

注意:如您所见,我正在使用打字稿,应该没问题。

所以我正在尝试的是:

//动作

describe('creating actions', () => {
    it('should create an action to get companies', () => {
        const expectedAction = {
            type: CompaniesActionTypes.GET_COMPANIES,
            payload: Promise.resolve()
        }
        expect(actions.getCompanies()).toEqual(expectedAction)
    })
})

对于第一个动作测试,我收到此错误:

  

预期:{“有效负载”:{},“类型”:“ @@ companies / GET_COMPANIES”}   收到:[匿名函数]

const middlewares = [thunk]
const mockStore = configureMockStore(middlewares)

describe('actions', () => {
    afterEach(() => {
        fetchMock.restore()
    })

    it('creates GET_COMPANIES when fetching companies', () => {
        fetchMock.getOnce('app/admin/client/companies', {
            body: mock,
            headers: { 'content-type': 'application/json' }
        })
        const expectedActions = [{ type: CompaniesActionTypes.GET_COMPANIES, payload: mock }]
        const store = mockStore({})
        return store.dispatch(actions.getCompanies()).then(() => {
            expect(store.getActions()).toEqual(expectedActions)
        })
    })
})

在此示例中,我在调度上遇到了问题:

- Expected
+ Received

  Array [
    Object {
-     "payload": Array [
-       Object {
-         "id": 1,
-         "name": "Company Test 1",
+     "type": "@@companies/LOADING_COMPANIES",
    },
    Object {
-         "id": 2,
-         "name": "Company Test 2",
-       },
-       Object {
-         "id": 3,
-         "name": "Company Test 3",
-       },
-     ],
-     "type": "@@companies/GET_COMPANIES",
+     "payload": "There was an error while requesting list of companies, please try again later.",
+     "type": "@@companies/ERROR_COMPANIES",
    },
  ]

发生了什么:

  • “类型”:“ @@ companies / LOADING_COMPANIES”,
  • “类型”:“ @@ companies / GET_COMPANIES”,
  • “类型”:“ @@ companies / ERROR_COMPANIES”,

有什么主意如何管理此方案进行测试?我想这是因为时间安排,但我不知道如何执行所有步骤

1 个答案:

答案 0 :(得分:0)

根据您的代码,我写了几行代码来解决针对多个调度问题的写作测试。

在这里,我的action.js具有多个调度。和你的差不多。

import axios from "axios";
// import { CompaniesActionTypes } from "./types";

export const getCompanies = () => async dispatch => {
  dispatch({
    type: "LOADING"
  });
  try {
    const response = await axios.get("app/admin/companies");
    dispatch({
      type: "GET_COMPANIES",
      payload: response.data

    });
  } catch (error) {
    console.log(error.message);
    dispatch({
      type: "ERROR",
      payload:
        "There was an error while requesting list of companies, please try again later."
    });
  }
};

下一步是为这些调度编写测试。首先,redux文档对这个问题的解释非常好。这里的链接(https://redux.js.org/recipes/writing-tests/#writing-tests 最后我的测试是这样的:

import configureMockStore from "redux-mock-store";
import thunk from "redux-thunk";
import * as actions from "./newAction";
// import * as types from "../../constants/ActionTypes";
import fetchMock from "fetch-mock";
// import expect from "expect"; // You can use any testing library
const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);
describe("async actions", () => {
  afterEach(() => {
    fetchMock.restore();
  });
  it("creates FETCH_TODOS_SUCCESS when fetching todos has been done", () => {
    fetchMock.getOnce("/todos", {
      body: { todos: ["do something"] },
      headers: { "content-type": "application/json" }
    });
    const expectedActions = [
      { type: "LOADING" },
      {
        type: "ERROR",
        payload:
          "There was an error while requesting list of companies, please try again later."
      }
    ];
    const store = mockStore({ todos: [] });
    return store.dispatch(actions.getCompanies()).then(async () => {
      try {
        const response = await axios.get("app/admin/companies");
        const expectedActionsSuccess = [
          { type: "LOADING" },
          {
            type: "ERROR",
            payload: response.data
          }
        ];

        expect(store.getActions()).toEqual(expectedActionsSuccess);
      } catch (e) {
        expect(store.getActions()).toEqual(expectedActions);
      }
    });
  });
});

它将处理多个调度。为了解决此问题,我创建了两种expectedAction。一个是成功的,另一个是错误的,与操作文件类似,它使用了try and catch块来处理从服务器接收错误。