我是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来测试状态吗?
非常感谢。
答案 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)
})