使用 useState 对内部状态进行 React Hook 测试
React Hook test with useState for internal state
我一直在研究大量资源,通过使用 useState 和 React Hook 来测试内部状态,但仍然找不到满意的答案,一些测试用例正在从 mount
或 shallow
将显示在 UI 侧而不是从组件的内部状态 (useState
) 显示,如果组件不在 UI 侧公开状态值怎么办,因为示例:
const TestComponent = () => {
const [count, setCount] = React.useState(0);
return (
<span>
<button id="count-up" type="button" onClick={() => setCount(count + 1)}>Count Up</button>
</span>
);
}
如何编写测试用例来测试
1) 当组件挂载时,我的内部状态count
会被初始化为0?
2) 当组件在按钮 count-up
上模拟一个 onClick
事件时,我的 setCount
应该被调用并且我的内部状态 count
应该变为 1?
可以在React上使用jest.spyOn
查看组件是否调用了setState
hook,举个简单的测试例子:
import React from "react";
import App from "./app";
import Enzyme, { shallow } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
Enzyme.configure({ adapter: new Adapter() });
describe("App", () => {
it("should call setState with initial values on component mount", () => {
const mockSetState = jest.spyOn(React, "useState");
shallow(<App />);
expect(mockSetState).toHaveBeenCalledTimes(1);
expect(mockSetState).toHaveBeenCalledWith(5);
});
});
您也可以将 useState
移动到一个单独的文件中,并将其用作自定义挂钩(可能是一个不必要的层,所以由您决定)
// useCounter.js
import { useState, useCallback } from "react";
const useCounter = initialValue => {
const [count, setValue] = useState(initialValue);
const setCount = useCallback(x => setValue(x), []);
return { count, setCount };
};
export default useCounter;
// usage: app.js
function App() {
const { count, setCount } = useCounter(5);
return (
<div className="App">
<h1>Testing React Hooks</h1>
<p>{count}</p>
<button onClick={() => setCount(count - 1)}>-</button>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
然后你可以对 "custom" 挂钩进行测试:
import { renderHook, act } from "@testing-library/react-hooks";
import useCounter from "./useCounter";
test("should increment counter", () => {
const { result } = renderHook(() => useCounter(0));
act(() => {
result.current.setCount(1);
});
expect(result.current.count).toEqual(1);
});
Code Sandbox 上的工作示例
我一直在研究大量资源,通过使用 useState 和 React Hook 来测试内部状态,但仍然找不到满意的答案,一些测试用例正在从 mount
或 shallow
将显示在 UI 侧而不是从组件的内部状态 (useState
) 显示,如果组件不在 UI 侧公开状态值怎么办,因为示例:
const TestComponent = () => {
const [count, setCount] = React.useState(0);
return (
<span>
<button id="count-up" type="button" onClick={() => setCount(count + 1)}>Count Up</button>
</span>
);
}
如何编写测试用例来测试
1) 当组件挂载时,我的内部状态count
会被初始化为0?
2) 当组件在按钮 count-up
上模拟一个 onClick
事件时,我的 setCount
应该被调用并且我的内部状态 count
应该变为 1?
可以在React上使用jest.spyOn
查看组件是否调用了setState
hook,举个简单的测试例子:
import React from "react";
import App from "./app";
import Enzyme, { shallow } from "enzyme";
import Adapter from "enzyme-adapter-react-16";
Enzyme.configure({ adapter: new Adapter() });
describe("App", () => {
it("should call setState with initial values on component mount", () => {
const mockSetState = jest.spyOn(React, "useState");
shallow(<App />);
expect(mockSetState).toHaveBeenCalledTimes(1);
expect(mockSetState).toHaveBeenCalledWith(5);
});
});
您也可以将 useState
移动到一个单独的文件中,并将其用作自定义挂钩(可能是一个不必要的层,所以由您决定)
// useCounter.js
import { useState, useCallback } from "react";
const useCounter = initialValue => {
const [count, setValue] = useState(initialValue);
const setCount = useCallback(x => setValue(x), []);
return { count, setCount };
};
export default useCounter;
// usage: app.js
function App() {
const { count, setCount } = useCounter(5);
return (
<div className="App">
<h1>Testing React Hooks</h1>
<p>{count}</p>
<button onClick={() => setCount(count - 1)}>-</button>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
}
然后你可以对 "custom" 挂钩进行测试:
import { renderHook, act } from "@testing-library/react-hooks";
import useCounter from "./useCounter";
test("should increment counter", () => {
const { result } = renderHook(() => useCounter(0));
act(() => {
result.current.setCount(1);
});
expect(result.current.count).toEqual(1);
});
Code Sandbox 上的工作示例