如何模拟实际上是 Redux 的连接动作创建者的道具?
How to mock props that actually are connected action creators of Redux?
在集成测试中,我想测试连接的动作创建器是否被调用。
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()
方法取代了 spy:
connect(mapStateToProps, { fancyActionCreator })(SomeContainer)
您使用商店安装了您的组件。如果您从 mount 调用中获取 return 值,它会为您提供反应元素的酶包装器。此包装器可用于针对商店分派操作:
const enzymeWrapper = mount(subject)
enzymeWrapper.node.store.dispatch({ type: "ACTION", data: "your fake data" });
但这是更多集成类型的测试,因为您正在使用 reducer 以及 Redux 存储状态与您的属性的连接。
这是我唯一可以用来测试 Redux 存储状态与组件属性的连接的测试。如果你以其他方式伪造属性,你可能会覆盖你的组件逻辑,但你缺少将属性连接到存储的部分。
我建议将您的组件分为展示组件和容器组件。 Presentational 不需要使用 store,因此您可以通过传递不同的属性来敲打它的逻辑。容器组件关注的是将商店连接到展示组件。因此,对于容器组件,您将使用我描述的测试类型。
对评论的反应:
实际上 presentational/unconnected 组件的 mount
与 shallow
的用法并不是那么简单。有时,您在展示组件上使用需要由挂载呈现的子组件(例如,react-select 出于某种原因需要 DOM)。
但通常是的,人们应该努力将 shallow
用于表示组件,除非您意识到自己需要 mount
:)。
在集成测试中,我想测试连接的动作创建器是否被调用。
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()
方法取代了 spy:
connect(mapStateToProps, { fancyActionCreator })(SomeContainer)
您使用商店安装了您的组件。如果您从 mount 调用中获取 return 值,它会为您提供反应元素的酶包装器。此包装器可用于针对商店分派操作:
const enzymeWrapper = mount(subject)
enzymeWrapper.node.store.dispatch({ type: "ACTION", data: "your fake data" });
但这是更多集成类型的测试,因为您正在使用 reducer 以及 Redux 存储状态与您的属性的连接。
这是我唯一可以用来测试 Redux 存储状态与组件属性的连接的测试。如果你以其他方式伪造属性,你可能会覆盖你的组件逻辑,但你缺少将属性连接到存储的部分。
我建议将您的组件分为展示组件和容器组件。 Presentational 不需要使用 store,因此您可以通过传递不同的属性来敲打它的逻辑。容器组件关注的是将商店连接到展示组件。因此,对于容器组件,您将使用我描述的测试类型。
对评论的反应:
实际上 presentational/unconnected 组件的 mount
与 shallow
的用法并不是那么简单。有时,您在展示组件上使用需要由挂载呈现的子组件(例如,react-select 出于某种原因需要 DOM)。
但通常是的,人们应该努力将 shallow
用于表示组件,除非您意识到自己需要 mount
:)。