因此,测试应该为函数提供输入并测试输出。使用 React,函数的输入可能来自其中一个props
或子组件/函数。好的,还有其他方法,但现在让我们看看这两种方法。
我有一个容器组件,它执行一些业务逻辑并呈现一个孩子:
import React, { useEffect } from 'react'
import ExampleView from './ExampleView'
const ExampleContainer = ({ onSomeBusinessDone, iHaveMounted }) => {
useEffect(() => {
// An example of a "on mount" style effect that we may need to test
// Grab data, do some initial logic whatever, but test that I call a prop
// within this mount call
iHaveMounted()
}, [])
const onDoSomeBussinessLogic = (eventData = {}) => {
// Do something with the data perhaps
eventData.whoa = true
onSomeBusinessDone(eventData)
}
return <ExampleView onSomething={onDoSomeBussinessLogic} />
}
export default ExampleContainer
该 Container 为子项提供回调样式prop
。目标是测试当孩子调用这个函数时,Container 用它做一些事情,然后调用它自己的回调样式 prop(也就是我们想要测试的输出)。
我遇到的问题是如何使用钩子触发在 Jest/React 中提供给孩子的这个函数?
这里的设置有点难以用语言解释,但我确实有一个 repo 和代码框:https: //github.com/Kikketer/hooks-test-questions https://codesandbox.io/embed/hooks-tests-问题-vvrv6
沙盒最适合查找,但我不知道如何在其中运行 jest,因此在克隆后尝试它是最容易的。
这里有几件事在起作用:
- 我不能使用浅渲染器,因为我还需要验证
useEffect
钩子调用属性。 - 我在 Container 函数中使用子组件的模拟渲染,这样它就不会尝试渲染子组件,因为我只是在测试 Container 我不需要担心该子组件的依赖关系或其他故障。只是我传递了有用和预期的道具。
我的测试如下所示:
jest.mock('./ExampleView', () => props => <div data-id="ExampleView" {...props} />)
...
...
test('when a child does something expect the prop function to have `whoa`', () => {
const onSomething = jest.fn()
act(() => {
renderer.create(<ExampleContainer onSomething={onSomething} />)
})
// Somehow trigger the child's action... not sure how
// Urm....
expect(onSomething).toHaveBeenCalledWith({ clicked: true, whoa: true })
})
我再次模拟视图,因为我不能使用浅渲染器并且我不想渲染孩子。我只想验证道具(快照做得很好)。
我是如何使用类做到这一点的
在钩子之前,我可以进入组件并直接调用一个函数:
const onSomeBusinessDone = jest.fn()
const iHaveMounted = jest.fn()
const component = new ExampleContainer({onSomeBusinessDone, iHaveMounted})
component.onDoSomeBussinessLogic({clicked: true})
// I can check to see that given the input (clicked) I get the output:
expect(onSomeBusinessDone).toHaveBeenCalledWith({clicked: true, whoa: true})
我意识到创建一个new
反应组件是不受欢迎的,但这将使我能够非常简单地运行这个测试。我不相信我能用 Hooks 做类似的格式,因为它是一个不暴露内部函数的函数。