In NextJs 13+ using the experimental App folder, async server components can be written, as described by the documentation:
export default async function Page({ params: { username } }) {
// Initiate both requests in parallel
const artistData = getArtist(username);
const albumsData = getArtistAlbums(username);
// Wait for the promises to resolve
const [artist, albums] = await Promise.all([artistData, albumsData]);
return (
<>
<h1>{artist.name}</h1>
<Albums list={albums}></Albums>
</>
);
}
This is a very useful technique that I have implemented in many pages of my app. However, when testing with jest, I find that I am unable to write any tests that are able to render this default export:
it('should render without crashing', async () => {
...(setup mocks)
const { container } = await waitFor(() => render(<Page params={{ username: 'Bob Dylan' }} />));
});
Any attempt to render the component or call it manually results in the following error:
Uncaught [Error: Objects are not valid as a React child (found: [object Promise])
Has anyone been able to correctly implement a Jest test using an async server component?
At the moment there's no official way to do it. You can use this workaround:
it('should render without crashing', async () => {
// ...(setup mocks)
render(await Page({params: {username: 'Bob Dylan' }}))
});
It's not perfect but it's the current solution. Check out this issue for more info.
You can test async components that don't use other RSC or app router features with React 18.3 (canary):
import { render, screen } from '@testing-library/react';
import { Suspense } from 'react';
import Page from './page';
it('should render without crashing', async () => {
render(
<Suspense>
<Page params={{ username: 'Bob Dylan' }} />
</Suspense>
);
await screen.findByRole('heading');
expect(screen.getByRole('listitem')).toBeInTheDocument();
});
You may want to use a custom render
function to simplify test setup if your suite heavily relies on async components.
If you need other RSC (i.e. server actions) or app router (i.e. layouts) features you can use hard coding, mocks, or an e2e test framework until we figure out native RSC rendering in #1209.
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