在 ES6 中使用 Jest 测试 React Flux Store

Testing React Flux Store with Jest in ES6

我正在尝试使用 Jest 和 ES6 类 测试我的 React 商店。我想知道如何在每次测试前 "reset" 测试商店或获取新实例。

我的商店包含:

import BaseStore from './BaseStore';
import { MIDI_PLUGIN_LOADED } from '../constants/MidiConstants';


class MidiStore extends BaseStore {

  constructor() {
    super();
    this.subscribe(() => this._registerToActions.bind(this));
    this._midiPlayer = null;
  }

  _registerToActions(action) {
    switch (action.actionType) {
      case MIDI_PLUGIN_LOADED:
        this._midiPlayer = action.player;
        this.emitChange();
        break;
    }
  }

  get midiPlayer() {
    return this._midiPlayer;
  }
}

export default new MidiStore();

我的 Jest 测试代码:

import { MIDI_PLUGIN_LOADED } from '../../constants/MidiConstants';
import AppDispatcher from '../../dispatchers/AppDispatcher';
import MidiStore from '../MidiStore';

describe('MidiStore', () => {

  var actionMidiPluginLoaded = {
    actionType: MIDI_PLUGIN_LOADED,
    player: true
  };

  it('stores global midi plugin', () => {
    AppDispatcher.dispatch(actionMidiPluginLoaded);
    let {
      midiPlayer
    } = MidiStore;

    expect(midiPlayer).toBe(true);
  });

  // fails cause midiPlayer = true
  it('should initialize with no player', () => {
    let {
      midiPlayer
    } = MidiStore;

    expect(midiPlayer).toBeNull();
  });

});

问题是第二个 "it" 语句失败了,因为 MidiStore 在第一个 运行 之后没有重置。

我知道切换两个 "it" 语句会通过两个测试,但这不是真正的解决方案。

在 ES5 Jest 中,可以在 beforeEach 中调用 var MidiStore = require('../MidiStore); 以在每个 运行 上获得一个新实例。我如何使用 ES6 完成此操作?

我自己设法解决了这个问题。通过在 jests beforeEach 回调中使用 "old" require 可以为每个测试函数获取一个新实例。

import { MIDI_PLUGIN_LOADED } from '../../constants/MidiConstants';

jest.mock('../../dispatchers/AppDispatcher');

describe('MidiStore', () => {

  var AppDispatcher;
  var MidiStore;
  var callback;

  var actionMidiPluginLoaded = {
    actionType: MIDI_PLUGIN_LOADED,
    player: true
  };

  beforeEach(() => {
    jest.resetModules();
    AppDispatcher = require('../../dispatchers/AppDispatcher').default;
    MidiStore = require('../MidiStore').default;
    callback = AppDispatcher.register.mock.calls[0][0];
  });

  it('registers a callback with the dispatcher', () => {
    expect(AppDispatcher.register.mock.calls.length).toBe(1);
  });

  it('stores global midi plugin', () => {
    callback(actionMidiPluginLoaded);
    expect(MidiStore.midiPlayer).toBe(true);
  });

  it('should initialize with no player', () => {
    expect(MidiStore.midiPlayer).toBeNull();
  });

});

beforeEach 调用中,我使用 jest.resetModules(); 重置模块并获取调度程序、存储和注册回调的新实例。已注册的回调从调度程序中检索,现在由 jest 模拟。为了实现模拟函数(在其他测试中),我参考了 https://facebook.github.io/jest/docs/api.html#mockfn-mockimplementation-fn