如何在React中测试变化的状态?

时间:2019-09-06 02:20:05

标签: reactjs jestjs react-testing-library

我是React的新手,它试图使用jest&testing-library / react测试我的代码。

我做了一个简单的选择框,并在该框上触发了更改事件。 我想要的只是获得状态,但我仍然不知道如何获得状态。

这是我的组件:

import React from "react";
import ReactDOM, { render } from "react-dom";
import NativeSelect from "@material-ui/core/NativeSelect";

const MyTest = () => {
  const [option, setOption] = React.useState("1");

  const handleChange = React.useCallback(e => {
    setOption(e.target.value);
  }, []);

  return (
    <div>
      <h3>selected : {option}</h3>
      <NativeSelect
        inputProps={{ "data-testid": "test-input" }}
        value={option}
        onChange={handleChange}
      >
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
      </NativeSelect>
    </div>
  );
};

export default MyTest;

这是测试:

import React from "react";
import { renderHook, act } from "@testing-library/react-hooks";
import { render, fireEvent } from "@testing-library/react";
import MyTest from "./MyTest";

test("should change state", () => {
  const { result } = renderHook(() => MyTest());

  let { getByTestId } = render(<MyTest />);
  const selectNode = getByTestId("test-input");
  expect(selectNode).not.toBeNull();

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

  expect(result.current.option).toBe("2");
});

codesandbox在这里: https://codesandbox.io/s/distracted-wave-j5fed?fontsize=14

然后来自测试的错误消息是 : “比较两种不同类型的值。应为字符串,但未定义。”

我猜“ result.current.option”是获取状态的错误方法... 如何获取组件的状态?

另外,根据我搜索的内容,可以使用酶很容易地测试道具和状态。

如果这是正确的,我应该使用酶而不是react-testing-library来测试状态吗?

非常感谢。

1 个答案:

答案 0 :(得分:2)

这两个是不同的对象:

const { result } = renderHook(() => MyTest());

let { getByTestId } = render(<MyTest />);

result.current.option 是未定义的,因为 result 是返回的组件,而不是挂钩函数。

要么测试状态,要么测试渲染的组件。

对于测试组件:

在您的测试中,它应该是:expect(selectNode.value).toBe("2") 或者您从文档中遵循以下要求:https://reactjs.org/docs/hooks-faq.html#how-to-test-components-that-use-hooks

用于测试挂钩的状态。您应该提取一个自定义钩子,然后像这样进行测试。

来自https://github.com/testing-library/react-hooks-testing-library

function useCounter() {
  const [count, setCount] = useState(0)

  const increment = useCallback(() => setCount((x) => x + 1), [])

  return { count, increment }
}

test('should increment counter', () => {
  const { result } = renderHook(() => useCounter())

  act(() => {
    result.current.increment()
  })

  expect(result.current.count).toBe(1)
})