【问题标题】:Jest: `querySelector` returns null in test of a ReactJS component开玩笑:`querySelector` 在 ReactJS 组件的测试中返回 null
【发布时间】:2020-10-24 19:20:27
【问题描述】:

我正在使用 jest 和 react-testing-library 在 ReactJS 中测试一个连接的功能组件。

该组件呈现一些输入字段和一个按钮。这是它的简化版本,我决定保留 GridContainerGridItem 组件的完整结构(来自 Material-UI),因为它们可能会在这个问题中发挥作用:

export function Letter(props) {
  const [letter, setLetter] = useState({
    // not relevant
  });

  return (
    <GridContainer>
      <GridItem md={6} sm={6}>
        <GridContainer>
          <GridItem>
            <LetterImageUpload />
          </GridItem>
          <GridItem>
            <LetterText />
          </GridItem>
        </GridContainer>
      </GridItem>
      <GridItem md={6} sm={6}>
        <LetterAddress />
        <GridContainer>
          <Button
            data-testid="AddToStoreButton"
            onClick={() => {
              props.addToStore(letter);
            }}
          >
            Add to Store
          </Button>
        </GridContainer>
      </GridItem>
    </GridContainer>
  );
}

function mapDispatchToProps(dispatch) {
  return {
    addToStore: letter => {
      dispatch({ type: "ADD_TO_STORE", payload: letter });
    }
  };
}

export default connect(
  null,
  mapDispatchToProps
)(Letter);

如您所见,我导出了哑组件连接的组件(后者通过export default),这样我就可以在我的测试中只使用import { Letter } 而不必担心redux商店(这是正确的方式吗?)。

附带的测试如下:

import { Letter } from "components/Letter/Letter.js";

let container = null;
beforeEach(() => {
  container = document.createElement("div");
  document.body.appendChild(container);
});

afterEach(() => {
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});

test("Letter", () => {
  act(() => {
    render(<Letter addToStore={jest.fn()} />, container);
  });
  // FIXME: querySelector returns null
  container.querySelector('[data-testid="AddToStoreButton"]').simulate("click");
  // assert
});

在调试器中,我可以看到 querySelector 返回 null,无论我使用什么选择器。 例如,我在实时调试器中尝试了以下操作:

> container.querySelector('[data-testid="AddToCartButton"]')
null
> container.querySelector("button")
null
> container.querySelector("div")
null

我显然做错了什么。有人能看出来吗?

【问题讨论】:

  • 我刚刚扫描的docs 不像您那样使用container,而是导入的screen 对象。 render() 方法还返回一个具有container 属性的对象,该属性可用于测试组件。
  • 有趣。我关注的是来自 ReactJS.org 的testing recipes,但我现在意识到那里的render 组件来自"react-dom",而不是反应测试库。我会尝试按照您的提示进行操作。

标签: javascript reactjs jestjs


【解决方案1】:

按照Anthony 的提示,原来我使用的是 react 测试库中的 render,但实际上使用的是“react-dom”库导出的那个。

完整的解决方案using the react testing library 如下所示:

import { fireEvent, render } from "@testing-library/react";

test("Letter", () => {
  const { getByTestId } = render(<Letter addToStore={() => {}} />);
  fireEvent.click(getByTestId("AddToStoreButton"));
  // assert
});

只是为了添加更多上下文,如果您遵循Testing Recipes on ReactJS.org 中显示的方法,则需要改为import { render } from "react-dom"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 1970-01-01
    • 2022-07-29
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    相关资源
    最近更新 更多