I've successfully tested one isolated server component by using an async it
and awaiting the output of a call to the component as a plain function to pass into render:
it('renders the user data when user is authenticated', async () => {
render(await UserData())
expect(screen.getByTestId('user-data')).toBeInTheDocument();
});
^ That works and passes.
But I also have a page.tsx server component that renders another server component -- <UserData />
-- nested within it:
'use server'
import styles from './page.module.css';
import LogInOut from "./LogInOut/LogInOut";
import UserData from "./UserData";
export default async function Page() {
return (
<main className={styles.main}>
<h1>Title</h1>
<LogInOut/>
<UserData />
</main>
);
}
// Note: LogInOut is a client component, removing it doesn't help the problem.
... and if I try the same technique to test this component, i.e.:
it('renders a heading', async () => {
render(await Page());
const heading = screen.getByRole('heading', { level: 1 });
expect(heading).toBeInTheDocument();
});
^ ...this does not work -- I get an error that reads:
Error: Uncaught [Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.]
How can we test nested server components? I want a solution that allows me to render both the parent and descendent server component in a unit test, without mocking one or the other.
testing-library/react-testing-library
issue 1209 and, for illustration,vitejs/vite-plugin-react
issue 325. – Chez