测试窗口用Jest重新加载Redux减速器

时间:2017-12-07 21:42:58

标签: javascript unit-testing redux react-redux jest

我有一个返回window.location.reload()的reducer。它是通过按钮单击调用的动作创建者触发的。

我试图在Jest中模拟这个功能,并且能够在reducer中测试它,返回一个窗口重新加载。我如何有效地模拟这个?

我认为这是一个很好的主题,因为测试重载可能适用于许多其他复杂情况。对于我来说,可能很容易没有涉及到Redux并且只是将它直接移动到按钮React组件(其React)的按钮onClick()属性。

但是,我仍然想知道在Jest中模拟窗口方法的最佳方法是什么,其他人也可以。

以下是我所拥有的:

动作

export const cancelEdits = () => ({
    type: CANCEL_EDITS,
});

减速

case Actions.CANCEL_EDITS:
    return window.location.reload();

玩笑

import * as Actions from "wherever";
it("should handle CANCEL_EDITS", () => {
    const action = { type: Actions.CANCEL_EDITS };
    const mockFn = jest.fn().mockImplementation(() => window.location.reload());
    expect(commonReducer(state, action)).toEqual(mockFn);
});

我嘲笑在reducer中被触发的动作,然后测试它等同于Jest mock函数,它返回window.location.reload()

然而,我想到的另一个选择是使用redux-mock-store模拟商店并让它调度cancelEdits()动作创建者,它应该触发动作,然后在减速器测试文件中,我会断言mockFn是这样调用的:

store.dispatch(Actions.cancelEdits()) expect(mockFn).toHaveBeenCalled()

不确定这是否可行。我也知道jest.spyOn()方法但是如何实现呢?

关于此的任何信息都会很棒!

1 个答案:

答案 0 :(得分:0)

使用jest.fn(implementation)创建模拟方法并将其替换为window.location

例如

reducer.js

import * as Actions from './actions';

export function commonReducer(state, action) {
  switch (action.type) {
    case Actions.CANCEL_EDITS:
      return window.location.reload();
    default:
      return state;
  }
}

actions.js

export const CANCEL_EDITS = 'CANCEL_EDITS';

export const cancelEdits = () => ({
  type: CANCEL_EDITS,
});

reducer.test.js

import { commonReducer } from './reducer';
import * as Actions from './actions';

describe('47704309', () => {
  it('should handle CANCEL_EDITS', () => {
    const state = {};
    const action = { type: Actions.CANCEL_EDITS };
    const mReload = jest.fn();
    window.location.reload = mReload;
    expect(commonReducer(state, action)).toEqual(undefined);
    expect(mReload).toBeCalledTimes(1);
  });

  it('should handle default case', () => {
    const state = {};
    const action = { type: '' };
    expect(commonReducer(state, action)).toEqual({});
  });
});

具有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/47704309/reducer.test.js (8.958s)
  47704309
    ✓ should handle CANCEL_EDITS (6ms)
    ✓ should handle default case (1ms)

------------|----------|----------|----------|----------|-------------------|
File        |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
------------|----------|----------|----------|----------|-------------------|
All files   |     87.5 |      100 |       50 |      100 |                   |
 actions.js |    66.67 |      100 |        0 |      100 |                   |
 reducer.js |      100 |      100 |      100 |      100 |                   |
------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        10.308s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/47704309