酵素を使用して、モカとアサートを期待しています。
私のユニットテストの目的は、mergePropsで一時停止していても一時停止していないときに、ディスパッチが正しい引数で呼び出されることを確認することです。私はストアの状態を動的に変更する必要があります:paused: true
。
現時点では、ディスパッチして一時停止中の値を更新しようとしていますが、これは単なるモックであり、実際にレデューサーを通過することはないため、これは正しくないと思います。
私はパッケージ 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
は、構成されたモックストアのインスタンスを返します。アクションによって状態が変化することはありません。アクションが渡されたレコードのみが渡されました。背後にある理由は、「統合」(状態+コンポーネント)テストではなく、単体テストを作成するためのユーティリティツールであるためです。
それでも、状態の変化をシミュレートできます。 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' });
あなたができることはあなたのテストで実際の店を使うことです。最初に、レデューサー関数を作成します。
const reducer = (state, action) => {
if (action.type === actionTypes.player.UPDATE_OPTION) {
return {
...state,
players: {
...state.players,
[action.id]: {
...state.players[action.id],
[action.key]: action.value,
},
},
};
}
return state;
};
(このテストで他の状態を保持しないことに問題がない場合は、上記を単純化して新しい状態を返すだけでよいことに注意してください。)
次に、そのレデューサーと初期状態でストアを作成します。
import { createStore } from 'redux';
const store = createStore(reducer, {
players: {
'audio-player-1': { paused: false }
}
});
これで、updateOption
を使用したディスパッチは新しい状態になります。