I have just updated to new versions of react and testing-library and now I see this warning in my hook's test file:
Warning: It looks like you're using the wrong act() around your test interactions.
Be sure to use the matching version of act() corresponding to your renderer:
// for react-dom:
import {act} from 'react-dom/test-utils';
//...
act(() => ...);
// for react-test-renderer:
import TestRenderer from 'react-test-renderer';
const {act} = TestRenderer;
//...
act(() => ...);
in TestHook
in Suspense
Here is code of my test:
import { fireEvent } from '@testing-library/react';
import { renderHook, act } from '@testing-library/react-hooks';
// ...
it('should update return value on hover', () => {
jest.useFakeTimers();
const ref = createRefMock();
const { result } = renderHook(() => useHover(ref));
expect(result.current).toBe(false);
fireEvent.mouseOver(ref.current);
act(() => {
jest.runOnlyPendingTimers();
});
expect(result.current).toBe(true);
fireEvent.mouseOut(ref.current);
expect(result.current).toBe(false);
});
Warning appears on line fireEvent.mouseOut(ref.current);
And if I change it to
act(() => {
fireEvent.mouseOut(ref.current);
});
everything is working fine.
But is still strange that I don't have any problems with fireEvent.mouseOver.
Do I need to wrap every fireEvent to act in my code?
same problem
Same problem
But by looking at the code of @testing-library/react you can see that fireEvent is just a little wrapper around the fireEvent of @testing-library/dom to add React.act
So this seems to work :
import { fireEvent } from '@testing-library/dom';
import { renderHook, act } from '@testing-library/react-hooks';
// ...
it('should update return value on hover', () => {
jest.useFakeTimers();
const ref = createRefMock();
const { result } = renderHook(() => useHover(ref));
expect(result.current).toBe(false);
act(() => {
fireEvent.mouseOver(ref.current);
});
act(() => {
jest.runOnlyPendingTimers();
});
expect(result.current).toBe(true);
act(() => {
fireEvent.mouseOut(ref.current);
});
expect(result.current).toBe(false);
});
Of course exporting an already wrapped fireEvent in @testing-library/react-hooks would be a nice to have.
This library does not have any direct dependency on @testing-library/react or @testing-library/dom. In fact we don't have any requirement on the DOM at all. This allows us to be agnostic to the user's target and test custom hooks for more use cases (e.g. react-native).
I'm closing this now as I don't think there is anything for use to do here and the solution proposed by @flaviendelangle should cater for most (all?) use cases involving fireEvent.
Found the solution here to be helpful also in a scenario where you want to render a hook and then use RTL to render a component (e.g, an input) and then fireChange on that input.
const { result } = renderHook(() => useInputValue(""));
render(<input data-testid="input" type="text" {...result.current} />);
const input = screen.getByTestId("input");
act(() => {
fireEvent.change(input, { target: { value: "Example" } });
});
expect(result.current.value).toBe("Example");
(Of course, I could be going about this the wrong way but this helped getting an already passing test to pass without a big red warning!)
Thanks @marclemagne, I'm sure that will help someone searching for this kind of thing in the futre.
However, wouldn't it just be easier just rendering a component that uses the hook? Untested, but I'm thinking something like:
const TestComponent = () => {
const inputValue = useInputValue("");
return <input data-testid="input" type="text" {...inputValue} />
}
render(<TestComponent />);
const input = screen.getByTestId("input");
act(() => {
fireEvent.change(input, { target: { value: "Example" } });
});
expect(input.value).toBe("Example");
This way, the component rerenders when the hook state changes and you get more confidence that the values spread onto the target input element after updates correctly.
It is telling me that createRefMock(); is not defined. Where it comes from ?
Hi @Isis-Yamel,
Usually I prefer new questions be raised as new issues if they are (seemingly) unrelated to what is being already discussed.
That said, I don't know. It's not part of this library nor is it something we call directly. If I had to guess, I'd say react-test-renderer and if I had to guess why I'd say you've got your versions of it and react out of sync.