React Testing Library: Test if children are passed / rendered correctly
The problem is that you're rendering once, in the describe
block. This probably doesn't work how you think. Code in describe
blocks that isn't inside a test
(or other jest function like beforeEach
) gets run ahead of time by Jest. In general you never want any code inside a describe
block but outside a test
(or other jest function).
You could either render the component in a beforeEach
or have a render helper function you call in each test.
I forked your sandbox here with the above approach and both tests now pass: https://codesandbox.io/s/v3wk1vlx3l
Comments
-
J. Hesters almost 2 years
I'm writing a React app using TypeScript. I use material-ui for my components and react-testing-library for my unit tests.
I'm writing a wrapper for material-ui's Grid component so that I always have a container.
import Grid from "@material-ui/core/Grid"; import withStyles, { WithStyles } from "@material-ui/core/styles/withStyles"; import React, { PureComponent } from "react"; import styles from "./styles"; export interface OwnProps { className?: string; } export interface Props extends WithStyles<typeof styles>, OwnProps {} export interface DefaultProps { className: string; } export class GridContainer extends PureComponent<Props & DefaultProps> { static defaultProps: DefaultProps = { className: "" }; render() { const { classes, children, className, ...rest } = this.props; return ( <Grid data-testid="grid-container" container={true} {...rest} className={classes.grid + " " + className} > {children} </Grid> ); } } export default withStyles(styles)(GridContainer);
I want to write a test that checks if it's children are rendered correctly. Here is what I wrote:
import "jest-dom/extend-expect"; import React from "react"; import { cleanup, render } from "react-testing-library"; import GridContainer, { OwnProps } from "./GridContainer"; afterEach(cleanup); const createTestProps = (props?: object): OwnProps => ({ ...props }); describe("GridContainer", () => { const props = createTestProps(); const { getByTestId } = render( <GridContainer {...props}> <div data-testid="child" /> </GridContainer> ); const container = getByTestId("grid-container"); describe("rendering", () => { test("it renders it's children", () => { expect(container.children.length).toBe(1); expect(getByTestId("child")).toBeDefined(); }); }); });
The problem is the test's first part where I check for the length of the children passes. But the
expect(getByTestId("child")).toBeDefined();
fails with:● GridContainer › rendering › it renders it's children Unable to find an element by: [data-testid="child"] <body /> 24 | test("it renders it's children", () => { 25 | expect(container.children.length).toBe(1); > 26 | expect(getByTestId("child")).toBeDefined(); | ^ 27 | }); 28 | }); 29 | }); at getElementError (node_modules/dom-testing-library/dist/query-helpers.js:30:10) at getAllByTestId (node_modules/dom-testing-library/dist/queries.js:231:45) at firstResultOrNull (node_modules/dom-testing-library/dist/query-helpers.js:38:30) at getByTestId (node_modules/dom-testing-library/dist/queries.js:241:42) at Object.getByTestId (src/components/Grid/GridContainer/GridContainer.test.tsx:26:14)
Is it not possible to give a data-testid to an element in the render function? How could I test that the children get rendered correctly?
EDIT Here is the output from debug:
● Console console.log node_modules/react-testing-library/dist/index.js:57 <body> <div> <div class="MuiGrid-container-2 GridContainer-grid-1 " data-testid="grid-container" > <div data-testid="child" /> </div> </div> </body>