web-dev-qa-db-ja.com

Reactテストライブラリ:子が渡されるか、正しくレンダリングされるかテストします

TypeScriptを使用してReactアプリを作成しています。コンポーネントにmaterial-uiを使用し、ユニットテストにreact-testing-libraryを使用しています。

Material-uiのグリッドコンポーネントのラッパーを書いているので、常にコンテナーを持っています。

_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);
_

子が正しくレンダリングされるかどうかをチェックするテストを記述したいと思います。これが私が書いたものです:

_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();
    });
  });
});
_

問題は、子供が合格する長さを確認するテストの最初の部分です。しかし、expect(getByTestId("child")).toBeDefined();は次のエラーで失敗します:

_● 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)
_

Render関数の要素にdata-testidを与えることはできませんか?子供が正しくレンダリングされることをどのようにテストできますか?

[〜#〜] edit [〜#〜]これはデバッグからの出力です:

_● 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>
_
3
J. Hesters

問題は、describeブロックで一度レンダリングすることです。これはおそらくあなたの考えではうまくいかないでしょう。 describe(またはtestのような他のjest関数)内にないbeforeEachブロックのコードは、Jestによって事前に実行されます。一般に、describeブロックの内側ではなく、test(または他のjest関数)の外側のコードは必要ありません。

コンポーネントをbeforeEachでレンダリングするか、各テストで呼び出すレンダリングヘルパー関数を使用できます。

私は上記のアプローチでサンドボックスをここに分岐し、両方のテストが成功しました: https://codesandbox.io/s/v3wk1vlx3l