javascript - 使用 Jest 测试窗口重新加载 Redux reducer

标签 javascript unit-testing redux react-redux jestjs

我有一个返回 window.location.reload() 的 reducer 。它由单击按钮时调用的 Action 创建器触发。

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

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

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

这是我得到的:

Action

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

reducer

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

开 Jest

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 中被触发的 Action ,然后测试它是否等同于 Jest 模拟函数,它返回一个 window.location.reload()

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

store.dispatch(Actions.cancelEdits()) 期望(mockFn).toHaveBeenCalled()

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

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

最佳答案

使用 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

关于javascript - 使用 Jest 测试窗口重新加载 Redux reducer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47704309/

相关文章:

javascript - onclick 也重定向到 "form action"

javascript - 为什么在 karma 和 jasmine 中运行测试时 fs.readFile 不是一个函数?

javascript - 为需要 ng-model 的 Angular Directive(指令)编写单元测试

unit-testing - 通过 Gallio 将 Resharper 单元测试运行器用于 MSTest

string - 检查 JSX 中的空字符串

reactjs - 基本的 redux 概念 - 如何启动 reducer

javascript - ScriptManager使用AJAX从WebService异步获取数据并抛出错误?

javascript - 如何构建一个每天调用另一个javascript文件的Java文件?

reactjs - 在客户端和服务器端渲染不同的组件

javascript - Chrome 扩展程序从后台脚本启动 browser_action 弹出窗口