使用酶,摩卡和期望断言。
我的单元测试的目的是检查在暂停时是否使用正确的参数调用dispatch,而不是在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,
}),
答案 0 :(得分:10)
configureMockStore
是一个工厂,用于通过应用中间件来配置模拟存储。返回mockStore
个对象
mockStore
返回已配置的模拟商店的实例。它不会通过行动改变国家。只是通过行动传递记录。背后的原因是因为它是一个实用工具来创建单元测试,而不是&#34;集成&#34; (州+组成部分)测试。
尽管如此,您可以模拟状态变化。 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' });
答案 1 :(得分:1)
您可以做的是在测试中使用真实的存储。首先,创建一个reducer函数:
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;
};
(注意,如果您可以在此测试中不保留其他状态,可以简化上述操作,然后返回一个新状态。)
然后使用该reducer和初始状态创建一个商店:
import { createStore } from 'redux';
const store = createStore(reducer, {
players: {
'audio-player-1': { paused: false }
}
});
这样,用updateOption
进行的分派将导致进入新状态。
答案 2 :(得分:-1)
现在看来,感谢pr by @catarinasoliveira,您可以提供真正的减速器,相应地更新商店。它掌握在主人手中,但我不知道它是否已经在npm,或坦率地说,如果它是我刚刚说的那样,但是我要尝试一下并报告回来