reactjs - React testbibliotek: Testattribut/prop


Jag skriver en React-app med TypeScript. Jag använder material-ui för mina komponenter och react-testing-library för mina enhetstester.

Jag skriver ett wrapper för material-uis Grid-komponent så att jag alltid har ett item.

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 GridItem extends PureComponent<Props & DefaultProps> {
  static defaultProps: DefaultProps = {
    className: ""
  };

  render() {
    const { classes, children, className, ...rest } = this.props;
    return (
      <Grid
        data-testid="grid-item"
        item={true}
        {...rest}
        className={classes.grid + " " + className}
      >
        {children}
      </Grid>
    );
  }
}

export default withStyles(styles)(GridItem);

Jag vill skriva ett enhetstest som kontrollerar om item={true}. Jag försökte använda hjälpbiblioteket jest-doms toHaveAttribute på detta sätt:

import "jest-dom/extend-expect";
import React from "react";
import { cleanup, render } from "react-testing-library";
import GridItem, { OwnProps } from "./GridItem";
afterEach(cleanup);

const createTestProps = (props?: object): OwnProps => ({
  ...props
});

describe("Parallax", () => {
  const props = createTestProps();
  const { getByTestId } = render(<GridItem {...props} />);
  describe("rendering", () => {
    test("it renders the image", () => {
      expect(getByTestId("grid-item")).toHaveAttribute("item", "true");
    });
  });
});

Men det här testet misslyckas med:

● GridItem › rendering › it renders the image

    expect(element).toHaveAttribute("item", "true") // element.getAttribute("item") === "true"

    Expected the element to have attribute:
      item="true"
    Received:
      null

      14 |   describe("rendering", () => {
      15 |     test("it renders the image", () => {
    > 16 |       expect(getByTestId("grid-item")).toHaveAttribute("item", "true");
         |                                        ^
      17 |     });
      18 |   });
      19 | });

      at Object.toHaveAttribute (src/components/Grid/GridItem/GridItem.test.tsx:16:40)

Test Suites: 1 failed, 3 passed, 4 total
Tests:       1 failed, 3 passed, 4 total
Snapshots:   0 total
Time:        1.762s, estimated 2s
Ran all test suites related to changed files.

Hur kan jag testa om ett element har ett visst attribut?

Svar #1

Assertionen jest-dom toHaveAttribute bekräftar item attribut medan testet försöker testa item egenskap.

item-egenskapen leder inte nödvändigtvis till item-attribut, och eftersom det är ett icke-standard attribut kommer det troligen inte att göra det.

react-testing-library sprider funktionell testning och kontrollerar resulterande DOM, detta kräver att man är medveten om hur komponenter fungerar. Som kan ses här resulterar item-props i att en klass läggs till på gridelementet.

Alla enheter utom den testade bör mocks i enhetstester, t.ex.:

...
import GridItem, { OwnProps } from "./GridItem";

jest.mock("@material-ui/core/Grid", () => ({
  default: props => <div data-testid="grid-item" className={props.item && item}/>
}));

Då kan det påstås som:

  expect(getByTestId("grid-item")).toHaveClass("item");

Svar #2

Om någon fortfarande har detta problem löste jag det på detta sätt:

it('Check if it is a materialUI Grid item', () => {
    //Rendering the component in a constant.
    const { container } = render(<YourComponent />); 
    //Accessing the grid wrapper. In this case by the attribute you provided.
    const grid = container.querySelector('[data-testid="grid-item"]'); 
    //What we are expecting the grid to have.  
    expect(grid).toHaveClass('MuiGrid-item');
})

Anteckningar :

  1. Jag märkte att i kodobjektet har det deklarerats som en sträng och inte som en boolean: item='true', vilket kommer att trigga en varning när du kör testet. item={true} är det korrekta sättet att deklarera det. Faktiskt när du skriver item i en grid i Material UI är det förstås som standard true, enligt min åsikt är det inte nödvändigt.
  2. item är en klass inom Material UI Grid som det tidigare svaret korrekt föreslog. Så enligt det bör det korrekta klassnamnet som ska refereras i detta fall vara 'MuiGrid-item'.

Relaterade artiklar