Using Jest with Async Server Components
Asked Answered
G

1

9

I'm trying to test a React Server Component, which returns a Promise. The standard render method in Jest doesn't like that.

I checked the similar questions, but all are > 4 years old and deal with componentDidMount etc.

/// Home.tsx
async function Home(props: Props) : Promise<JSX.Element> {
 // call async functions to setup component
}

/// home.test.ts
describe('Home', () => {
  it('renders a heading', () => {
     render(<Home />);
  }
}

Error:

'Home' can not be used as a JSX element

Any suggestions on how to work around this? An obvious solution is to make the component not return a Promise, but than I'm writing code to satisfy the test framework which is not ideal.

Goshorn answered 21/4, 2023 at 14:58 Comment(6)
What is jests standard render method?Amigo
Objects are not valid as react children. Are you using Next? Set up your component with something like getServerSideProps then pass that to your component.Amigo
render is not part of Jest. You must be using some other library for that. Are you using react-testing-library?Nash
render is most likely from react-testing-library, but this is not very important to the question at hand. There is no documentation on how to test React Server Components that are available in Next.JS 13.4. If anyone has achieved this, an answer would be awesome!Inquiring
WIP docs: github.com/testing-library/react-testing-library/issues/…Danieladaniele
@Paul van Brenk Can you check your React version please? Easiest way is import { version } from "react". If you're using a meta framework like Next, don't use package.json.Danieladaniele
D
2

Happened upon this while looking through the bounties. I am not sure what all you have tried but I may be able to help. Obviously you know that Jest's can't return a Promise. However there may be a workaround by using act from test-utils. Try something like this

import { render } from '@testing-library/react';
import { act } from 'react-dom/test-utils';

describe('Home', () => {
  it('renders a heading', async () => {
    await act(async () => {
      render(await Home());
    });
  });
});
Distinguish answered 16/5, 2023 at 23:45 Comment(3)
Does this actually work? We expect answers to be verified, not speculative.Dialogize
It does work but without the full code I can't confirm that it will work in this specific case. However I have used it before to get around a similar issueDistinguish
This isn't a complete integration testing solution as it doesn't support async child components or other React Server Component features like Server Actions and Next app router.Danieladaniele

© 2022 - 2024 — McMap. All rights reserved.