我正在尝试使用 Jest 和 ES6 类测试我的 React 存储。我想知道如何在每次测试之前“重置”测试的商店或获取新的实例。
我的商店包含:
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 中,可以在
var MidiStore = require('../MidiStore);
中调用 beforeEach
来在每次运行时获取一个新实例。我怎样才能用 ES6 来完成这个?
我自己设法解决了这个问题。通过在笑话
require
回调中使用“旧”beforeEach
,可以为每个测试函数获取一个新实例。
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
感谢您的回答,只是想知道为什么 AppDispatcher 不会被 Jest 自动嘲笑,而不是本文档中写的内容 https://legacy.reactjs.org/blog/2014/09/24/testing-flux- applications.html?