【问题标题】:How to test react components props (expect component to be called with)如何测试反应组件道具(期望组件被调用)
【发布时间】:2021-12-29 07:27:18
【问题描述】:

我需要测试在触发按钮单击后使用 opened={true} 属性调用反应组件。我正在使用testing-library (testing-library/react + testing-library/jest-dom)。

我使用类似的东西模拟了组件

import Component from "./path-to-file/component-name"
...
jest.mock("./path-to-file/component-name", () => {
  return jest.fn().mockImplementation(() => {
    return null
  })
})

我第一次尝试:

expect(Component).toBeCalledWith(expect.objectContaining({"opened": true}))
expect(Component).toHaveBeenCalledWith(expect.objectContaining({"opened": true}))
expect(Component).toHaveBeenLastCalledWith(expect.objectContaining({"opened": true}))

但我得到了Error: expect(jest.fn()).toBeCalledWith(...expected)。

expect.objectContaining({"opened": expect.anything()}) 也是如此

甚至对于expect(Component).toBeCalledWith(expect.anything())

而不同的是空数组:

我也试过expect(ChartMenu.mock).toBeCalledWith(expect.anything())。我得到了一个不同的错误但仍然无法正常工作(这次错误是Error: expect(received).toBeCalledWith(...expected) + Matcher error: received value must be a mock or spy function)

谢谢你的建议!

编辑:这是我要测试的组件的简化版本:

const Component = () => {
  const [chartMenuOpened, setChartMenuOpened] = useState(false)
  return (
      <Flex>
        <EllipseIcon onClick={() => setChartMenuOpened(true)}>
          +
        </EllipseIcon>
        <ChartMenu
          opened={chartMenuOpened}
          close={() => setChartMenuOpened(false)}
        />
      </Flex>
  )
}

基本上,我想确保单击+ 图标时,将打开菜单(或使用打开值调用)。问题是我无法渲染 ChartMenu,因为它需要多个 props 和 redux 状态。

我最终能够模拟 useState 以检查 setState 是否从图标组件中正确调用(以确保组件未来不会发生会破坏此 using this post 的更改) .

但我仍然非常感谢这个问题的答案:是否有任何方法可以在反应组件上创建间谍或类似的东西并检查调用它的道具?主要是因为这是一个相当简单的例子,我只有一个状态。但情况可能并非总是如此。或者关于如何正确测试这种交互是否真的很受欢迎的任何好主意。

【问题讨论】:

  • 请提供您要测试的组件代码。
  • 嗨!我编辑了这个问题。非常感谢!

标签: reactjs jestjs react-testing-library testing-library


【解决方案1】:

我认为您在测试组件是否已使用该道具调用的正确轨道上,这可能是您代码中的语法问题

我从同事那里学到了这个技巧,您可以尝试看看这是否有助于解决您的问题。

expect(Component).toHaveBeenCalledWith(
  expect.objectContaining({
    opened: true,
  }),
  expect.anything()
);

【讨论】:

  • 嗨!非常感谢您的意见。不幸的是,它并没有解决我的问题。我收到类似的错误:ibb.co/JQ4JKXj
  • 别担心,从您的错误消息中,我可以看出它失败的原因是 opened 设置为 false,因此它也可能与您测试中的其他区域有关。
  • 哦,是的!你说的对。我很愚蠢(我嘲笑 React.setState 作为一种解决方法,所以它并没有真正改变状态值)。无论如何,这行得通!非常感谢!如果您有解释,我将不胜感激,但无论哪种方式,您的解决方案都是有效的,所以我会接受。谢谢!
  • 因此,如果您删除 expect.anything() 并让此测试失败,那么您将看到您的组件被调用了什么。在这种情况下,应该有多个使用 Component 调用的参数,但这些东西不是你关心的,所以你松散地匹配单个重要的东西 opened: true,所以你使用 expect.anything 来匹配组件的任何随机参数在您的测试中被调用。这有意义吗?
  • 正确,我也尝试将{} 作为第二个参数,但不确定为什么会有第二个参数,至少我们现在知道它是如何工作的 ?
猜你喜欢
  • 2017-11-20
  • 1970-01-01
  • 2016-04-28
  • 2021-04-07
  • 2019-06-30
  • 2023-03-12
  • 2020-12-25
  • 2021-10-01
  • 1970-01-01
相关资源
最近更新 更多