How to fix getByText, getByRole etc cannot be used outside of a render call in React

ReactBEGINNERMEDIUMUpdated Dec 11, 2025· 105 views

This error occurs when you try to use React Testing Library query methods (getByText, getByRole, etc.) without first rendering a component. These queries require a DOM tree to search within, which only exists after calling render(). The fix involves ensuring all queries are called after render() and using the screen object correctly.

Quick fix

Fixes getByText, getByRole etc cannot be used outside of a render call

import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';

test('should render component', () => {
  // First render the component
  render(<MyComponent />);

  // Now queries will work
  const button = screen.getByRole('button', { name: /submit/i });
  expect(button).toBeInTheDocument();
});
  1. Always call render() before any queries
  2. Use the screen object for all queries
  3. Check test structure for misplaced queries
  4. Use findBy* for async elements
react — error
import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';
test('should render component', () => {
// First render the component
render(<MyComponent />);
// Now queries will work
const button = screen.getByRole('button', { name: /submit/i });
expect(button).toBeInTheDocument();
});
getByText, getByRole etc cannot be used outside of a render call

What this error means

React Testing Library query methods like getByText, getByRole, queryByText, and findByText are designed to search within a rendered DOM tree. When you call these methods without first rendering a React component using the render() function, there is no DOM tree to search, causing this error. The Testing Library ecosystem follows a specific workflow: first render your component, then query the resulting DOM. This pattern ensures tests resemble how users interact with your application and helps avoid testing implementation details. This error is particularly common for developers transitioning from Enzyme or other testing libraries that have different APIs, or when trying to use queries in test setup functions (beforeEach, beforeAll) without proper rendering.

Typical symptoms

  • Test fails with error: "getByText, getByRole etc cannot be used outside of a render call"
  • Queries return undefined or throw errors when used in test setup before render()
  • Attempting to use screen.getBy* methods without calling render() first
  • Trying to query elements in a test that hasn't rendered any React component
  • Error occurs in describe blocks or beforeEach hooks where queries are used prematurely

Common causes

  1. Calling Testing Library queries before the render() function has been invoked (most common)
  2. Using queries in test setup (describe blocks, beforeAll, beforeEach) without rendering first
  3. Attempting to reuse query instances or component references between tests without re-rendering
  4. Misunderstanding the render cycle and when the DOM is available for querying
  5. Importing query methods incorrectly or using them outside of test context
  6. Trying to test utility functions or hooks that don't render UI directly with UI queries

How to fix "getByText, getByRole etc cannot be used outside of a render call"

1Always call render() before any queries

The render() function must be called before any query methods. It creates the DOM tree that queries search within.

javascript
import { render, screen } from '@testing-library/react';
import MyComponent from './MyComponent';

test('should render component', () => {
  // First render the component
  render(<MyComponent />);

  // Now queries will work
  const button = screen.getByRole('button', { name: /submit/i });
  expect(button).toBeInTheDocument();
});

Important: render() should be called inside each test or in a beforeEach hook that runs before each test.

2Use the screen object for all queries

Prefer using the screen object imported from @testing-library/react rather than destructuring queries from render(). This is the recommended pattern and avoids common pitfalls.

javascript
// ✅ Recommended pattern
import { render, screen } from '@testing-library/react';

test('example', () => {
  render(<MyComponent />);
  const element = screen.getByText(/hello/i);
  expect(element).toBeInTheDocument();
});

// ❌ Avoid this pattern (can lead to issues)
import { render } from '@testing-library/react';

test('example', () => {
  const { getByText } = render(<MyComponent />);
  const element = getByText(/hello/i); // Works but not recommended
});

The screen object is pre-bound to document.body and works consistently across your test suite.

3Check test structure for misplaced queries

Ensure queries are not placed in describe blocks, beforeAll, or beforeEach hooks (unless render is called there first). Queries should be inside test/it blocks after render.

javascript
// ❌ Wrong - query in beforeEach without render
describe('MyComponent', () => {
  beforeEach(() => {
    const button = screen.getByRole('button'); // Error! No render yet
  });

  test('example', () => {
    // ...
  });
});

// ✅ Correct - render in beforeEach, query in test
describe('MyComponent', () => {
  beforeEach(() => {
    render(<MyComponent />); // Render first
  });

  test('should have button', () => {
    const button = screen.getByRole('button'); // Works!
    expect(button).toBeInTheDocument();
  });
});

// ✅ Also correct - render in each test
describe('MyComponent', () => {
  test('should have button', () => {
    render(<MyComponent />);
    const button = screen.getByRole('button');
    expect(button).toBeInTheDocument();
  });
});
4Use findBy* for async elements

If you need to query elements that appear asynchronously (after state updates, API calls, etc.), use findBy* queries which return Promises and automatically wait.

javascript
import { render, screen } from '@testing-library/react';

test('async element', async () => {
  render(<AsyncComponent />);

  // findBy* waits for element to appear (default timeout: 1000ms)
  const asyncElement = await screen.findByText(/loaded/i);
  expect(asyncElement).toBeInTheDocument();

  // You can also use waitFor for more complex async scenarios
  await waitFor(() => {
    expect(screen.getByText(/loaded/i)).toBeInTheDocument();
  });
});

Note: findBy* queries still require render() to be called first.

5Debug and verify component rendering

If you're still getting the error, verify that your component renders without throwing errors. Use the debug() utility or add console logs.

javascript
import { render, screen } from '@testing-library/react';

test('debug render', () => {
  // Debug what gets rendered
  const { debug } = render(<MyComponent />);
  debug(); // Prints the rendered DOM to console

  // Check if component rendered at all
  console.log(document.body.innerHTML);

  // Now queries should work
  const element = screen.getByText(/content/i);
});

// For more detailed debugging, increase verbosity
process.env.DEBUG_PRINT_LIMIT = 15000;

Also check for any errors in your component that might prevent rendering.

6Test non-UI code appropriately

If you're testing utility functions, custom hooks, or other non-UI code, don't use Testing Library UI queries. Instead, test them directly or use renderHook for hooks.

javascript
// Testing a custom hook - use renderHook
import { renderHook } from '@testing-library/react';
import { useCounter } from './useCounter';

test('custom hook', () => {
  const { result } = renderHook(() => useCounter());
  expect(result.current.count).toBe(0);
});

// Testing a utility function - test directly
import { formatDate } from './utils';

test('utility function', () => {
  expect(formatDate('2023-01-01')).toBe('January 1, 2023');
});

Testing Library queries are specifically for testing rendered UI components.

Advanced notes

### Understanding the Testing Library Philosophy

React Testing Library is built on the principle of testing components the way users interact with them. The requirement to render before querying enforces this pattern:

1. User-centric testing: Users don't interact with React component instances; they interact with rendered DOM elements.
2. Implementation detail avoidance: By querying the DOM, you avoid testing internal component state or methods.
3. Accessibility focus: Queries like getByRole encourage accessible markup.

### Technical Details

Under the hood, render() uses:
- ReactDOM.render (React 17 and earlier)
- React 18's createRoot (with concurrent features)
- jsdom or happy-dom as the DOM environment in Jest

The resulting DOM tree is attached to document.body, which is what screen queries search.

### Common Pitfalls

1. Test isolation: Each test should render fresh. Avoid sharing rendered components between tests.
2. Cleanup: Use cleanup() or configure test framework to auto-cleanup to prevent test pollution.
3. Async rendering: For React 18 concurrent features, use await act() or findBy* queries.
4. Custom render: If using providers (Redux, Router), create a custom render function.

### Migration from Enzyme

If migrating from Enzyme, remember:
- Enzyme's wrapper.find() works on React elements
- Testing Library queries work on DOM nodes
- The mental model shift is from "component instance" to "rendered output"

Frequently asked questions

What does "getByText, getByRole etc cannot be used outside of a render call" mean?
React Testing Library query methods like getByText, getByRole, queryByText, and findByText are designed to search within a rendered DOM tree. When you call these methods without first rendering a React component using the render() function, there is no DOM tree to search, causing this error. The Testing Library ecosystem follows a specific workflow: first render your component, then query the resulting DOM.
How do I fix "getByText, getByRole etc cannot be used outside of a render call"?
This error occurs when you try to use React Testing Library query methods (getByText, getByRole, etc.) without first rendering a component. These queries require a DOM tree to search within, which only exists after calling render(). The fix involves ensuring all queries are called after render() and using the screen object correctly.
What causes "getByText, getByRole etc cannot be used outside of a render call"?
Calling Testing Library queries before the render() function has been invoked (most common) Using queries in test setup (describe blocks, beforeAll, beforeEach) without rendering first Attempting to reuse query instances or component references between tests without re-rendering
Is the "getByText, getByRole etc cannot be used outside of a render call" error serious?
It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.

Official resources & further reading