在集成测试中,我想测试一个连接的动作创建者是否被调用。
describe('SomeContainer', () => {
let subject, store, fancyActionCreator
beforeEach(() => {
store = createStore(combineReducers({ /* ... */ }))
fancyActionCreator = sinon.spy()
const props = {
fancyActionCreator
}
subject = (
<Provider store={store}>
<SomeContainer {...props} />
</Provider>
)
})
it('calls fancyActionCreator on mount', () => {
mount(subject)
expect(fancyActionCreator.callCount).to.equal(1)
})
}
在componentWillMount
内调用动作创建者,并在测试环境之外按预期工作。
问题是原始的动作创建者在测试中被调用,并且没有被正确地嘲笑。
我感觉这是因为Redux的connect()
方法正在取代间谍:
connect(mapStateToProps, { fancyActionCreator })(SomeContainer)
答案 0 :(得分:2)
您使用商店安装了组件。如果你从mount调用中获取返回值,它会为你提供反应元素的酶包装。此包装器可用于针对存储分派操作:
const enzymeWrapper = mount(subject)
enzymeWrapper.node.store.dispatch({ type: "ACTION", data: "your fake data" });
但这是更多集成类型的测试,因为您正在使用Reducer以及Redux存储状态与您的属性的连接。
这是我唯一可以测试Redux存储状态到组件属性的连接的测试。如果你以别的方式伪造属性,你可能会覆盖你的组件逻辑,但你缺少将属性连接到存储的部分。
我建议将您的组件分为表示组件和容器组件。演示文稿不需要使用商店,因此您可以通过传递不同的属性来锤击其逻辑。容器组件关注的是将存储连接到表示组件。因此,对于容器组件,您将使用我所描述的测试类型。
评论的反应:
实际上,mount
vs shallow
对表示/未连接组件的使用并不是那么直接。有时您在演示组件上使用需要由mount渲染的子组件(例如,由于某种原因,react-select需要DOM)。
但通常是的,除非您意识到需要shallow
,否则应该努力将mount
用于表示组件。