如何在测试之间重置redux-test-utils存储

时间:2018-02-15 17:25:25

标签: javascript redux jestjs

我有一个订阅者根据提供给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方法重置模拟的商店对象吗?

1 个答案:

答案 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>