Jest tests hang or render nothing for components that call useContent
I write tests first, so this is blocking me. I have a hero component that calls useContent('home-hero'). In Jest with jsdom, render(<Hero />) produces an empty container, and findByRole from testing-library times out waiting for anything to appear.
I understand the hook fetches content, but I expected some kind of loading state to render. Following the testing-library guidance of testing behavior over implementation, I would rather not rewrite the component just to make it testable. How do others isolate components from the SDK in unit tests?
2 answers
The empty render is expected once you know the mechanism: useContent relies on React Suspense. While content resolves, the component suspends, and with no <Suspense> boundary above it there is nothing to show, so jsdom renders nothing and your async queries time out waiting for a fetch that never completes offline.
For unit tests, mock the hook module and keep the component untouched:
jest.mock('@croct/plug-react', () => ({ ...jest.requireActual('@croct/plug-react'), useContent: () => ({ title: 'Test headline', cta: 'Sign up', }),}));Now the component renders synchronously with fixture content and you can assert on behavior as usual.
If you prefer not to mock, wrap the render in the provider plus a Suspense boundary and assert the fallback appears first, but that turns it into an integration test with network concerns, which is rarely what you want in a unit suite.
The module mock did it, and it keeps the component API untouched, which is what I wanted. Tests are green. Thanks!
Adding two options for completeness since teams draw the line differently:
- Passing an initial or fallback value to useContent gives the component deterministic content to render without suspending forever, so some teams standardize on always providing one and asserting against it in tests.
- For integration-style runs where you keep the real provider, the plug options include a test mode flag that swaps in a mock transport, so nothing hits the network but the real code paths execute.
Module mocks for unit tests, test mode for integration tests is the split that has worked for us.