将 jest.fn() 函数传递给酶浅渲染中的 mapDispatchToProps
Posted
技术标签:
【中文标题】将 jest.fn() 函数传递给酶浅渲染中的 mapDispatchToProps【英文标题】:Pass jest.fn() function to mapDispatchToProps in enzyme shallow render 【发布时间】:2018-12-02 01:05:35 【问题描述】:有非常简单的组件:
从“prop-types”导入 PropTypes 从“反应”导入反应 从'react-redux'导入连接
class MyComponent extends React.Component
componentWillMount()
if (this.props.shouldDoSth)
this.props.doSth()
render ()
return null
MyComponent.propTypes =
doSth: PropTypes.func.isRequired,
shouldDoSth: PropTypes.bool.isRequired
const mapStateToProps = (state) =>
return
shouldDoSth: state.shouldDoSth,
const mapDispatchToProps = (dispatch) => (
doSth: () => console.log('you should not see me')
)
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)
我想测试当shouldDoSth
等于true
时是否调用doSth
。
我写了一个测试:
describe('call doSth when shouldDoSth', () =>
it('calls doSth', () =>
const doSthMock = jest.fn()
const store = mockStore(shouldDoSth: true)
shallow(<MyComponent doSth=doSthMock/>, context: store ).dive()
expect(doSthMock).toHaveBeenCalled()
)
)
但似乎虽然我将 doSth 作为道具传递,但在执行 console.log('im not a mock')
时,它会被 mapDispatchToProps
覆盖。
如何正确传递/覆盖/分配doSth
函数以使组件使用模拟而不是mapDispatchToProps
中的函数。或者,也许我正在做一些根本不应该被允许的事情,并且有“正确”的方式来测试我的案例。我应该只模拟调度并检查它是否使用正确的参数调用?
【问题讨论】:
【参考方案1】:我认为你需要弄清楚的一件事是你是否希望 doSth
成为一个道具,或者一个连接在 mapDispatchToProps 中的 redux 操作。
如果它是一个道具,那么您可以将它连接到父级(容器)中的 redux。从该组件的 mapDispatchToProps 中删除它。这将使组件更具可测试性。
如果你希望它是一个连接在这个组件中的redux action,那么将这个action移出这个组件是有意义的,比如actions.js
,将它导入到这个组件中,然后在测试中模拟它jest.mock('actions.js', () => (doSth: jest.mock()))
【讨论】:
【参考方案2】:导出未连接的组件并在测试中使用它,您将能够覆盖 mapDispatchToProps 操作。
export class MyComponent extends React.Component
componentWillMount()
if (this.props.shouldDoSth)
this.props.doSth()
render ()
return null
MyComponent.propTypes =
doSth: PropTypes.func.isRequired,
shouldDoSth: PropTypes.bool.isRequired
const mapStateToProps = (state) =>
return
shouldDoSth: state.shouldDoSth,
const mapDispatchToProps = (dispatch) => (
doSth: () => console.log('you should not see me')
)
export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)
import MyComponent from '../MyComponent'
describe('call doSth when shouldDoSth', () =>
it('calls doSth', () =>
const doSthMock = jest.fn()
const store = mockStore(shouldDoSth: true)
shallow(<MyComponent doSth=doSthMock/>, context: store ).dive()
expect(doSthMock).toHaveBeenCalled()
)
)
【讨论】:
【参考方案3】:我认为你应该问问自己是要测试未连接的 MyComponent 还是连接的。
这里有两个讨论可能对您有所帮助:Am I testing connected components correclty? 和 Can't reference containers wrapped in a Provider or by connect with Enzyme
如果您没有正确测试动作或状态,您可能会忘记 mapStateToProps 和 mapDispatchToProps(这些进程已经被 redux 测试过)并通过 props 传递值。
检查以下示例:
describe('MyComponent', () =>
let wrapper;
const doSthMock = jest.fn();
beforeEach(() =>
const componentProps =
doSth: true,
;
wrapper = mount(
<MyComponent
... componentProps
doSth=doSthMock
/>
);
);
it('+++ render the component', () =>
expect(wrapper.length).toEqual(1);
);
it('+++ call doSth when shouldDoSth', () =>
expect(doSthMock).toHaveBeenCalled();
);
)
【讨论】:
以上是关于将 jest.fn() 函数传递给酶浅渲染中的 mapDispatchToProps的主要内容,如果未能解决你的问题,请参考以下文章