Next.js Discord

Discord Forum

Testing Async Server Components

Unanswered
Savannah posted this in #help-forum
Open in Discord
SavannahOP
How do you unit test async server components? I use Jest for testing. jest.render fails with the 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."

If I (try) render(await <Component>) I get the same error. Obvious answer is not to use async. Is there another option?

5 Replies

Northeast Congo Lion
Hi Jeffo, I'm having the same question as you. Here is what I found.
Server Component
export type ResponseUser = {
  name: string
}

export async function RscUserList() {
  const res = await fetch('https://jsonplaceholder.typicode.com/users')
  const response = await res.json() as ResponseUser[]
  const data = response.map((user) => user.name)

  return (
    <div>
      <h1>Users</h1>
      <ul>
        {data.map(user => <li key={user}>{user}</li>)}
      </ul>
    </div>
  )
}
Mock Handler (using MSW)
import { ResponseUser } from '@/components/user-list';
import { rest } from 'msw';

export const handlers = [
  rest.get('https://jsonplaceholder.typicode.com/users', (req, res, ctx) => {
    const responseData: ResponseUser[] = [
      { name: 'Kurtis Weissnat' },
      { name: 'Nicholas Runolfsdottir V' },
      { name: 'Glenna Reichert' },
    ];
    return res(ctx.status(200), ctx.json(responseData));
  }),
];
Test (using jest and testing library)
import { render } from "@testing-library/react";
import { RscUserList } from "./rsc-user-list";

describe('RscUserList component', () => {
  test('renders correctly', async () => {
    const serverComponent = await RscUserList()
    const { getByRole } = render(serverComponent)
    const headingElement = getByRole('heading')
    expect(headingElement).toBeInTheDocument()
  })
  test('renders a list of users', async () => {
    const serverComponent = await RscUserList()
    const { getAllByRole } = render(serverComponent)
    const userElements = getAllByRole('listitem')
    expect(userElements).toHaveLength(3)
  })
});
Should you have a different approach, please let me know.