Redux如何在单元测试中更新商店?

Mar*_*son 11 unit-testing mocha.js reactjs redux enzyme

使用酶,摩卡和期望断言.

我的单元测试的目的是检查在暂停时是否使用正确的参数调用调度,而不是在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));
  });
});
Run Code Online (Sandbox Code Playgroud)

容器:

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);
Run Code Online (Sandbox Code Playgroud)

connectWithId:

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

动作:

updateOption: (key, value, id) => ({
    type: actionTypes.player.UPDATE_OPTION,
    key,
    value,
    id,
}),
Run Code Online (Sandbox Code Playgroud)

Luc*_*cas 12

configureMockStore是一个工厂,用于通过应用中间件来配置模拟存储.返回mockStore对象.
mockStore返回已配置的模拟存储的实例.它不会通过行动改变国家.只是通过行动传递记录.背后的原因是因为它是一个实用工具来创建单元测试,而不是"集成"(状态+组件)测试.

尽管如此,您可以模拟状态变化.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);
Run Code Online (Sandbox Code Playgroud)

然后在测试中,您可以:

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' }); 
Run Code Online (Sandbox Code Playgroud)

  • 如上所述,使用返回模拟状态的函数初始化模拟存储非常重要,`const store = mockStore(() =&gt; state);` 并且状态需要被覆盖,仅更改属性是行不通的 (3认同)