Consider the following component:
export default function Calc() {
useEffect(() => {
// do something
})
const Add = (x: number, y: number): number => {
return x + y;
}
return (<></>)
}
I realize that in React <= 16, one would use enzyme: shallow(<Calc />).instance().Add(2, 2)
. However, enzyme is no longer available in React 18 in favor of @testing-library/react
.
So, the question is, how do I unit test the 'Add' method in React 18?
Thanks!
For unit test the Add
method in React 18, You can use the @testing-library/react-hooks
package, which allows you to test custom hooks in isolation. The idea is to create a custom hook that wraps your component logic and exposes the Add
method as a return value. For example, you can do something like this:
import { useEffect } from "react";
export const useCalc = () => {
const Add = (x: number, y: number): number => {
return x + y;
};
return { Add };
};
export default function Calc() {
const { Add } = useCalc();
return <></>;
}
And then:
import { renderHook } from "@testing-library/react-hooks";
import { useCalc } from "./Calc";
test("Add method", () => {
const { result } = renderHook(() => useCalc());
expect(result.current.Add(2, 2)).toBe(4);
expect(result.current.Add(3, 5)).toBe(8);
});
If you use render
instead of renderHook
, you will still not be able to test the Add
method directly, because render
only returns the DOM elements rendered by your component, not the internal methods or state. You can only test the Add
method indirectly by simulating user interactions that trigger the method and checking the expected output or behavior. For example, if your component has a button that calls the Add
method and displays the result, you can use fireEvent
or userEvent
to click the button and use screen or getByText
to check the result. However, this is not a unit test, but an integration test, because it involves testing multiple parts of your component together. If you want to unit test the Add
method in isolation, you need to use renderHook
with a custom hook.
To learn more, please see react-hooks-testing-library-documentation
PS: Maybe you might wait for
@testing-library/react-hooks
to update their peer dependency requirement to support React 18.
To install this module:
npm install react-test-renderer@18 --save-dev
npm i @testing-library/react-hooks -D --legacy-peer-deps