# Rendering Components — Jest, Vitest & Testing Library

Source: https://www.skillbyai.com/en/javascript-testing/c-render

> render, screen and jest-dom matchers.

## render into a container, query via screen

`render(<Component {...props} />)` from `@testing-library/react` mounts the component into a container attached to `document.body`. Query it through **`screen`**, and assert with **`@testing-library/jest-dom`** matchers such as `toBeInTheDocument`, `toBeVisible`, `toBeDisabled`, `toHaveValue`, `toHaveTextContent` and `toHaveAccessibleName`. `rerender` re-renders with new props, and `unmount` lets you test cleanup. Testing Library unmounts after each test automatically **when the runner exposes a global `afterEach`**; with Vitest and `globals: false`, call `cleanup()` in your own `afterEach` (check the docs for your versions). Rendering and events are wrapped in React's `act()` for you, so you rarely need to call `act` directly.

## Render, interact, assert

A component test renders into a simulated DOM, drives it with realistic user events and checks the visible result.

![Three ideas: rendering, user interactions, async UI and hooks.](assets/figures/javascript-testing/section-6-map.svg) — Figure 6.1 — Render a component, interact like a user, wait for async updates.

## Rendering with props and rerender

A price label component.

```tsx
import { render, screen } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { PriceTag } from './PriceTag';

describe('PriceTag', () => {
  it('shows the formatted price', () => {
    render(<PriceTag amount={1999} currency="USD" />);
    expect(screen.getByText('$19.99')).toBeInTheDocument();
  });

  it('shows a sale badge when discounted', () => {
    const { rerender } = render(<PriceTag amount={1999} currency="USD" />);
    expect(screen.queryByText('Sale')).not.toBeInTheDocument();

    rerender(<PriceTag amount={1499} wasAmount={1999} currency="USD" />);
    expect(screen.getByText('Sale')).toBeInTheDocument();
    expect(screen.getByText('$19.99')).toHaveClass('line-through');   // acceptable: style is the behaviour here
  });
});
```

## Test the props a parent really passes

Render components with realistic props, ideally from shared factories, rather than the minimum that compiles. Edge-case props (empty lists, long names, missing optional fields) find more bugs than happy defaults.

**Quiz:** Where does @testing-library/jest-dom fit in?

- [ ] It replaces jsdom
- [ ] It renders React components
- [x] It adds DOM-specific matchers like toBeInTheDocument and toBeDisabled
- [ ] It mocks network requests

*Answer:* It adds DOM-specific matchers like toBeInTheDocument and toBeDisabled. Load it once in the setup file.
