1

我正在尝试在我的 react-redux 应用程序中学习/实现玩笑测试。我的测试失败,说接收到的不等于预期,但是,实际的 thunk 工作并将数据返回到我的应用程序。所以我要么写错了测试(我基本上是从 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 和这篇文章重新进行了测试,但我仍然遇到与上述相同的错误。

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。阅读本文后,我能够成功创建测试。

4

1 回答 1

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

于 2019-09-20T03:36:04.543 回答