用Jest进行React-Redux测试:收到的有效载荷=未定义

时间:2019-08-30 16:15:10

标签: redux jestjs redux-thunk fetch-mock

我正在尝试在我的react-redux应用程序中学习/实现玩笑测试。我的测试无法说接收到的内容与预期的不一样,但是实际的重击有效,并将数据返回给我的应用程序。因此,我写错了测试(基本上是从redux-docs复制/粘贴),或者写错了thunk。

动作


export const getOddGroups = () => {
    return dispatch => {
        return axios.get("/api/tables/oddgroups")
        .then(results => {
            dispatch({type: "GET_ODD_GROUPS", payload: results.data})
        }).catch(err => {
            dispatch({ type: "GET_ERRORS", payload: err.response.message })
        })
    }
}

测试

import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import * as oddActions from '../actions/OddActions';
import fetchMock from 'fetch-mock'


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


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

    it('creates GET_ODD_GROUPS when successful', () => {
        fetchMock.get("*", {
            results: { data: [{ "row1": "some data" }] },
            headers: { 'content-type': 'application/json' }
        })

        const expectedActions = [
            { type: "GET_ODD_GROUPS", results: { data: [{ "row1": "some data" }] } },
        ]
        const store = mockStore({ oddGroups: [] })

        return store.dispatch(oddActions.getOddGroups()).then(() => {
            // return of async actions
            expect(store.getActions()).toEqual(expectedActions)
        })
    })
})

测试结果输出:

 expect(received).toEqual(expected) // deep equality

    - Expected
    + Received

      Array [
        Object {
    -     "results": Object {
    -       "data": Array [
    -         Object {
    -           "row1": "some data",
    -         },
    -       ],
    -     },
    -     "type": "GET_ODD_GROUPS",
    +     "payload": undefined,
    +     "type": "GET_ERRORS",
        },
      ]

编辑-更新 在@CoryDanielson的建议下,我使用axios-mock-adapter和this post对测试进行了重新设计,但仍然遇到与上面相同的错误。

import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import * as oddActions from '../actions/oddActions';
import axios from "axios";
import MockAdapter from 'axios-mock-adapter';

const middlewares = [thunk]
const mockStore = configureMockStore(middlewares)
let mock = new MockAdapter(axios);

describe('query preview async actions', () => {

    beforeEach(function () {
        /*Not sure which one is best to use in this situation yet
        * will test both
        */

        mock.reset(); // reset both registered mock handlers and history items with reset
        //mock.restore(); //restore the original adapter (which will remove the mocking behavior)
    });

    it("return data for GET_ODD_GROUPS when successful", function (done) {
        mock.onGet("api/tables/oddGroups")
            .reply(function () {
                return new Promise(function (resolve, reject) {
                    resolve([200, { key: 'value' }]);
                });
            });

        const store = mockStore({ oddGroups: [] })
        store.dispatch(oddActions.getOddGroups()).then(() => {
            let expectedActions = [{ type: "GET_ODD_GROUPS", payload: { key: 'value' } }]
            console.log(store.getActions());
            expect(store.getActions()).toEqual(expectedActions);
        });
        setTimeout(() => {
            done();
        }, 1000)
    });
});

记录:

当我返回控制台状态console.log(store.getActions());时 它给了我错误的分派动作

console.log(store.dispatch(oddActions.getOddGroups()));返回Promise { <pending> }

最终解决方案:

在尝试了几次失败之后,我放弃了使用axios-mock-adapter并改用moxios。遵循this article之后,我就能够成功创建测试。

1 个答案:

答案 0 :(得分:0)

这是没有axios-mock-adapter的解决方案,不要在代码中添加太多内容,请保持简单。您可以自己手动模拟axios模块,请看下面的代码:

actionCreators.ts

import axios from 'axios';

export const getOddGroups = () => {
  return dispatch => {
    return axios
      .get('/api/tables/oddgroups')
      .then(results => {
        dispatch({ type: 'GET_ODD_GROUPS', payload: results.data });
      })
      .catch(err => {
        dispatch({ type: 'GET_ERRORS', payload: err.response.message });
      });
  };
};

actionCreators.spec.ts

import { getOddGroups } from './actionCreators';
import createMockStore from 'redux-mock-store';
import thunk, { ThunkDispatch } from 'redux-thunk';
import axios from 'axios';
import { AnyAction } from 'redux';

const middlewares = [thunk];
const mockStore = createMockStore<any, ThunkDispatch<any, any, AnyAction>>(middlewares);

jest.mock('axios', () => {
  return {
    get: jest.fn()
  };
});

describe('actionCreators', () => {
  describe('#getOddGroups', () => {
    let store;
    beforeEach(() => {
      const initialState = {};
      store = mockStore(initialState);
    });
    it('should get odd groups correctly', () => {
      const mockedResponse = { data: 'mocked data' };
      (axios.get as jest.MockedFunction<typeof axios.get>).mockResolvedValueOnce(mockedResponse);
      const expectedActions = [{ type: 'GET_ODD_GROUPS', payload: mockedResponse.data }];
      return store.dispatch(getOddGroups()).then(() => {
        expect(store.getActions()).toEqual(expectedActions);
        expect(axios.get).toBeCalledWith('/api/tables/oddgroups');
      });
    });

    it('should get odd groups error', () => {
      const mockedError = {
        response: {
          message: 'some error'
        }
      };
      (axios.get as jest.MockedFunction<typeof axios.get>).mockRejectedValueOnce(mockedError);
      const expectedActions = [{ type: 'GET_ERRORS', payload: mockedError.response.message }];
      return store.dispatch(getOddGroups()).then(() => {
        expect(store.getActions()).toEqual(expectedActions);
        expect(axios.get).toBeCalledWith('/api/tables/oddgroups');
      });
    });
  });
});

覆盖率100%的单元测试结果:

 PASS  src/stackoverflow/57730153/actionCreators.spec.ts
  actionCreators
    #getOddGroups
      ✓ should get odd groups correctly (5ms)
      ✓ should get odd groups error (2ms)

-------------------|----------|----------|----------|----------|-------------------|
File               |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-------------------|----------|----------|----------|----------|-------------------|
All files          |      100 |      100 |      100 |      100 |                   |
 actionCreators.ts |      100 |      100 |      100 |      100 |                   |
-------------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        2.934s, estimated 4s

以下是完整的演示:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57730153