2

因此,测试应该为函数提供输入并测试输出。使用 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,因此在克隆后尝试它是最容易的。

这里有几件事在起作用:

  1. 我不能使用浅渲染器,因为我还需要验证useEffect钩子调用属性。
  2. 我在 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 做类似的格式,因为它是一个不暴露内部函数的函数。

4

0 回答 0