unit-testing - Redux 如何在单元测试中更新存储?

标签 unit-testing reactjs redux mocha.js enzyme

使用 enzyme 、 Mocha 和期望断言。

我的单元测试的目的是检查在 mergeProps 中暂停和未暂停时是否使用正确的参数调用调度。 我需要动态更改商店的状态以执行以下操作:paused: true

目前,我尝试通过调度来更新暂停值,但我认为这是不正确的,因为它只是一个模拟,从未真正通过 reducer 运行。

我正在使用包redux-mock-store .

我该怎么做?

describe('Play Container', () => {
  const id = 'audio-player-1';

  const store = configureMockStore()({
    players: {
        'audio-player-1': { paused: false }
    }
  });
  let dispatchSpy;
  let wrapper;

  beforeEach(() => {
    dispatchSpy = expect.spyOn(store, 'dispatch');
    wrapper = shallow(
      <PlayContainer className={attributes.className}>
        {children}
      </PlayContainer>,
      { context: { id } },
      ).shallow({ context: { store } });
  });

  it('onClick toggles play if paused', () => {
    //Not Working
    store.dispatch(updateOption('paused', true, id));
    wrapper.simulate('click');
    expect(dispatchSpy).toHaveBeenCalledWith(play(id));
  });

  it('onClick toggles pause if playing', () => {
    wrapper.simulate('click');
    expect(dispatchSpy).toHaveBeenCalledWith(pause(id));
  });
});

容器:

const mapStateToProps = ({ players }, { id }) => ({
  paused: players[id].paused
});

const mergeProps = (stateProps, { dispatch }, { id }) => ({
  onClick: () => (stateProps.paused ? dispatch(play(id)) : dispatch(pause(id)))
});

export default connectWithId(mapStateToProps, null, mergeProps)(Play);

connectWithId:

//getContext() is from recompose library and just injects id into props
export const connectWithId = (...args) => compose(
  getContext({ id: React.PropTypes.string }),
  connect(...args),
);

行动:

updateOption: (key, value, id) => ({
    type: actionTypes.player.UPDATE_OPTION,
    key,
    value,
    id,
}),

最佳答案

configureMockStore 是一个工厂,用于通过应用指定的中间件来配置模拟存储。该工厂返回一个 mockStore 函数。

mockStore 函数本身返回已配置的模拟存储的实例。它不会通过 Action 改变状态;相反,它只记录通过了哪些操作。这是因为它是一个创建单元测试的实用工具,而不是“集成”(状态 + 组件)测试。

尽管如此,您可以模拟状态变化。 mockStore 接受一个函数,因此您可以执行以下操作:

import configureMockStore from 'redux-mock-store';

const middlewares = [];
const mockStore = configureMockStore(middlewares);

let state = {
  players: {
    'audio-player-1': { paused: false }
  }
};

const store = mockStore(() => state);

然后在您的测试中,您可以执行以下操作:

state = NEW_STATE;

// now you need to make the components update the state.
// so you can dispatch any action so the mock store will notify the subscribers
store.dispatch({ type: 'ANY_ACTION' }); 

关于unit-testing - Redux 如何在单元测试中更新存储?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41642041/

相关文章:

c# - RhinoMocks - 当一个方法被调用 n 次时,如何在 n - k 次调用中测试它的参数

c# - 单元测试自定义 IHttpactionResult

C#:如何对依赖于同一类中另一个方法的方法进行单元测试?

javascript - 使用 d3 更新 dom ref 并使用react

javascript - 分派(dispatch)操作后应用程序状态立即发生变化

javascript - 在按钮之间切换

javascript - 在 React Redux 应用程序中检测网络连接 - 如果离线,则对用户隐藏组件

java - 在没有 PowerMock 的情况下,在测试类之外的不同类中调用模拟方法

javascript - 导入 CommonJS 在 ES6 中无法正确解构

backbone.js - Flux+React 与 Backbone+React