'Tooltip MUI and React testing library
I'm trying to test an Info HOC on my react app :
const InfoHOC = (HocComponent) => ({ message }) => (
<>
<Tooltip title={message}>
<InfoIcon />
</Tooltip>
{HocComponent}
</>
);
export default InfoHOC;
I've simplified it. But as it's using material ui Tooltip component, I can't test if message is displayed on mouseover...
it('should display info message on <div /> mouseover', () => {
const Component = InfoHoc(<div>jest div</div>)({ message: 'jest infoHoc message' });
const { getByTitle, getByDisplayValue } = render(Component);
const icon = getByTitle('jest infoHoc message');
act(() => {
fireEvent(
icon,
new MouseEvent('mouseover', {
bubbles: true,
}),
);
});
expect(getByDisplayValue('jest infoHoc message')).toBeInTheDocument();
});
My last line is wrong... I think it's because mui tooltip display the message in a div at the end of the body, so not really in my rtl tree... BUT the first element of this tree is body ! I know that I should not test mui component, but here is not the purpose, I just want to be sure that InfoHoc has the right comportment, using mui tooltip or something else.
Here is the RTL tree after mouseover action :
<body>
<div>
<div
class="infoHoc"
>
<div>
jest div
</div>
<svg
aria-hidden="true"
class="MuiSvgIcon-root icon--right"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"
/>
</svg>
</div>
</div>
</body>
The event is good because icon has a title attr with message as value till mouseover is fired. As title attr is not here on my tree, I assume my event is well executed ;p
I am wrong testing that ? If not do you have an idea to solve my problem ?
Thank you all !
Solution 1:[1]
In case this can still help you, you need to findBy
instead of getBy
as the Tooltip
is showing the tooltip after a delay
it('should display info message on <div /> mouseover', async () => {
const Component = InfoHoc(<div>jest div</div>)({ message: 'jest infoHoc message' });
const { getByTitle, findByDisplayValue } = render(Component);
const icon = getByTitle('jest infoHoc message');
act(() => {
fireEvent(
icon,
new MouseEvent('mouseover', {
bubbles: true,
}),
);
});
// Wait for the tooltip to show up
const tooltipText = await findByDisplayValue('jest infoHoc message')
expect(tooltipText).toBeInTheDocument();
});
Side note 1: I am not sure if you really need the act
around fireEvent
. testing-library should do it for you.
Side note 2: you can use user-event which has a cleaner syntax (and a .hover
function)
Solution 2:[2]
I think this is the cleanest way.
it('Renders tooltip when hovering over button', async () => {
render(<Search />);
const button = await screen.findByRole('button');
await userEvent.hover(button);
const tip = await screen.findByRole('tooltip');
expect(tip).toBeInTheDocument();
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jeremy |
Solution 2 | httpete |