我有一个订阅者根据提供给pub事件的参数调度一个动作
// subscriptions.js
import store from '../store';
import { action } from '../actions';
export const subscribeToToggle = () => {
window.$.subscribe('action/toggle', (_e, isToggleOn) => {
if (isToggleOn=== true){
store.dispatch(action());
}
});
};
在我的测试文件中,我编写了2个测试,测试只有在提供true时才会发送操作。
// subscriptions.test.js
import { subscribeToToggle } from './subscriptions';
import jQuery from 'jquery';
import { actionTypes } from '../constants';
import store from '../store';
jest.mock('../store');
beforeEach(() => {
window.$ = jQuery;
window.$.unsubscribe('action/toggle');
});
test('Action not sent when false', () => {
subscribeToToggleOpen();
window.$.publish('action/toggle', false);
expect(store.getActions().length).toBe(0);
});
test('Action sent when true', () => {
subscribeToToggleOpen();
window.$.publish('action/toggle', true);
expect(store.getActions().length).toBe(1);
expect(store.getActions()[0].type).toBe(actionTypes.ACTION);
});
我使用redux-test-utils
有以下模拟商店import { createMockStore } from 'redux-test-utils';
let store = null;
store = createMockStore('');
export default store;
我面临的问题是我的测试仅在错误测试出现时才通过。如果他们是另一种方式,那么在假的情况下不会发送动作'测试失败,因为它看到了“真实时发送的动作”提供的动作'测试。
我有什么方法可以使用beforeEach方法重置模拟的商店对象吗?
答案 0 :(得分:1)
在这种情况下,问题是您的商店基本上是一个单身人士。当你试图做这样的事情并且通常是一种反模式时,这可能会产生问题。
如果您导出一个getStore()
函数,而不是导出商店对象,可能会被调用以获取商店。在这种情况下,您可以这样做:
getStore().dispatch(action());
在其中,您可以使用其他帮助函数来替换它返回的商店。该文件可能如下所示:
import { createMockStore } from 'redux-test-utils';
let store = createMockStore('');
export default () => store;
然后,在那里,您可以添加另一个resetStore
作为非默认导出:
export const resetStore = () => store = createMockStore('');
它在技术上仍然是一个单身人士,但它现在是一个你可以控制的单身人士。
然后,在测试的beforeEach()
中,只需致电resetStore()
:
import { resetStore } from '../store';
beforeEach(() => {
resetStore();
});
这还要求您更新实际代码以直接使用getStore()
代替store
,但从长远来看,这可能是一个有益的改变。
完整更新版本:
// subscriptions.js
import getStore from '../store';
import { action } from '../actions';
export const subscribeToToggle = () => {
window.$.subscribe('action/toggle', (_e, isToggleOn) => {
if (isToggleOn=== true){
getStore().dispatch(action());
}
});
};
// subscriptions.test.js
import { subscribeToToggle } from './subscriptions';
import jQuery from 'jquery';
import { actionTypes } from '../constants';
import getStore, { resetStore } from '../store';
jest.mock('../store');
beforeEach(() => {
window.$ = jQuery;
window.$.unsubscribe('action/toggle');
resetStore();
});
test('Action not sent when false', () => {
subscribeToToggleOpen();
window.$.publish('action/toggle', false);
expect(getStore().getActions().length).toBe(0);
});
test('Action sent when true', () => {
subscribeToToggleOpen();
window.$.publish('action/toggle', true);
expect(getStore().getActions().length).toBe(1);
expect(getStore().getActions()[0].type).toBe(actionTypes.ACTION);
});
import { createMockStore } from 'redux-test-utils';
let store;
export const resetStore = () => { store = createMockStore(''); }
resetStore(); // init the store, call function to keep DRY
export default () => store;
除此之外,另一种方法是拥有一个全局缩减器,它可以将商店的状态重置为默认值,但这样会更加混乱,我认为通常不会编写单元测试。< / p>