I have a custom function that show a user's card (returns JSX.Element) when the pointer is over the user's name. This component request user information using React Query, which I use for data-fetching in my app.
I'm trying to write a test for this function using Jest, react-test-renderer or @testing-library/react.
Function:
const link = (href: string, text: ReactNode[]): JSX.Element => {
return match(getServiceUrl(href))
.with({ service: 'users' }, (serviceUrl) => (
<UserCard href={recoverUrlFromInternal(href)} userId={serviceUrl.id} text={text.toString()} />
))
//.with(... some other cases
.exhaustive()
}
Component:
const UserCard = (props: { href: string; userId: string; text: string }) => {
const { href, userId, text } = props
const response = useGetApiV1UsersP1(userId)
return <PopoverCard input={response} />
}
I want to write a test for the link function and test all cases including displaying the UserCard component.
I found two ways to do this:
- Make a snapshot using
rendererfrom react-test-renderer, but I can't figure out how to wait for the request to complete. So my snapshot is:
<span>
Still loading. 0
</span>
- Use the
renderfrom @testing-library/react, but the problem is the same:
<span xmlns="http://www.w3.org/1999/xhtml">Still loading. 0</span>
In this case I can't figure out how to use the waitFor() function with render. In the hook case it's more simply:
const { result } = renderHook(() => useGetApiV1UsersP1('userId'), { wrapper })
await waitFor(() => {
expect(result.current.isSuccess).toBe(true)
})
Is it correct to use snapshots etc. to test functions like link? Maybe there is another way to test this function?
Or should I find a way how to wait for the request to complete?
Please let me know if you have any ideas or maybe you've tested something similar.
Test file:
//general part:
const queryClient = new QueryClient()
const Wrapper = (props: { children: any }) => (
<QueryClientProvider client={queryClient}>{props.children}</QueryClientProvider>
)
const expectation = nock('http://localhost')
.get('/api/v1/users/userId')
.reply(200, {
person: {
firstName: 'Bruce',
lastName: 'Lee',
}
})
//1st case:
describe('renderer test', () => {
describe('link', () => {
test('users', async () => {
const usersLink = renderer
.create(<Wrapper children={link(`#/v1/users/userId`, ['text'])} />)
.toJSON()
expect(usersLink).toMatchSnapshot()
})
})
})
//2nd case:
describe('renderer test', () => {
describe('link', () => {
test('users', async () => {
const serializer = new XMLSerializer()
const { asFragment } = render(link(`#/v1/users/userId`, ['text']), { wrapper })
await waitFor(() => {
//compare serializer.serializeToString(asFragment()) with ...?
})
})
})
})