测试是否已使用Jest调用React prop方法

时间:2019-03-02 16:48:07

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

我有一个Input组件,它接受prop方法并在用户键入内容时调用它。代码本身按预期工作,但是由于某些原因,测试失败。它认为没有调用prop方法。为什么会这样呢?为了进行测试,我使用了Jest和react-testing-library。

第二个问题。在实际应用中,我的想法是测试传递给该prop方法的参数。是否认为它是实施测试(我知道我应该对其进行测试)?

  

Input.js

export default function Input({ onChange }) {
  return <input onChange={onChange} />;
}
  

测试

import React from "react";
import { render, act, cleanup, fireEvent } from "react-testing-library";
import Input from "./input";

describe("Input tests", () => {
  afterEach(cleanup);

  it("Should call prop function", () => {
    const onChange = jest.fn();
    const { getByTestId } = render(<Input onChange={onChange} />);
    const input = getByTestId("input");

    act(() => {
      fireEvent.change(input, { target: { value: "Q" } });
    });

    expect(onChange).toHaveBeenCalled();
  });
});

https://codesandbox.io/s/y229669nvx

2 个答案:

答案 0 :(得分:1)

阅读此书后,看起来像是by design to not assert against events handlers。尽管显示为to work in React 16.5,但是使用16.8.x失败。如果您想测试这样的功能,建议使用酶。

使用react-testing-library进行测试失败(但是,您会注意到,运行测试时,输入的值实际上会发生变化):https://codesandbox.io/s/n3rvy891n4

使用enzyme进行测试成功:https://codesandbox.io/s/lx34ny41nl

答案 1 :(得分:0)

测试不起作用的原因是您使用getByTestId查找元素。 getByTestId寻找具有data-testid属性的DOM节点。

为了使您的考​​试通过,您有多种选择。

您可以将data-testid添加到input<input data-testid="input" onChange={onChange} />中。这会起作用,但是,最好尽可能避免使用测试ID。

在真实的应用程序中,您的输入将使用label进行渲染,我们可以利用它:

const { getByLabelText } = render(
  <label>
    My input
    <Input onChange={onChange} />
  </label>
)
const input = getByLabelText('My input')

另一种解决方案是使用container返回的值之一的render。就像RTL中的其他所有内容一样,它是一个DOM节点,因此您可以使用通常的DOM API:

const { container } = render(<Input onChange={onChange} />)
// Any of these would work
const input = container.firstChild
const input = container.querySelector('input')

作为旁注,我同意,与酶相比,RTL测试似乎更复杂。有充分的理由。 RTL促使您像黑盒子一样测试您的应用程序。一开始这很难做,但最终会导致更好的测试。

另一方面,

默认情况下,酶模拟大多数事情,并允许您与组件实现交互。以我的经验,这在一开始看起来比较容易,但是会产生脆弱的测试。

如果您需要入门方面的帮助,我建议您加入spectrum channel