Using react-testing-library, the following test works:
it( 'renders popular search terms, with links to search urls', () => {
waitFor(() => {
const popularSearch = screen.getByText( Copywriting.buyer.shop.popularSearch, {}, { timeout: 5000 })
expect( popularSearch ).toBeInTheDocument()
const popularSearchPills = screen.findAllByTestId( 'pill' )
expect( popularSearchPills.length ).toBeGreaterThan( 0 )
const hrefs = popularSearchPills.map( pill => pill.href )
expect( hrefs.filter( urlIsValidAndNotBaseUrl )).not.toHaveLength( 0 )
})
})
But the following test used to work, but now fails:
it( 'renders popular search terms, with links to search urls', async () => {
const popularSearch = await screen.findByText( Copywriting.buyer.shop.popularSearch )
expect( popularSearch ).toBeInTheDocument()
const popularSearchPills = await screen.findAllByTestId( 'pill' )
expect( popularSearchPills.length ).toBeGreaterThan( 0 )
const hrefs = popularSearchPills.map( pill => pill.href )
expect( hrefs.filter( urlIsValidAndNotBaseUrl )).not.toHaveLength( 0 )
})
Why would the two code snippets function differently? I thought findby was supposed to be a wrapper for waitfor.
Note: what's happening under the hood of the rendered component is that we dispatch an action which calls a saga, the saga calls fetch
, which returns a piece of data, the saga then calls another action with the data as a payload, triggering a reducer that saves the data to the store. The view should then update to include the element with Copywriting.buyer.shop.popularSearch
.
Is there any reason, on principle, why the two tests should have different outputs?
This allows you to waitFor things that must be checked asynchronously.
That could be because the default timeout is 1000ms (https://testing-library.com/docs/dom-testing-library/api-queries#findby) while in your first test you manually specify a 5000ms timeout.
You will also notice in the docs that the findBy*
methods accept the waitForOptions
as their third argument.
So you should
const popularSearch = await screen.findByText(Copywriting.buyer.shop.popularSearch, undefined, {
timeout: 5000
});
Now the two tests would be identical.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With