首页 > 解决方案 > ReactJS - 在组件中测试条件渲染

问题描述

我有一个使用 useEffect 从文件中获取数据的组件。在组件中,我有一个条件,如果我们有数据,它只会显示组件的内容。

现在如何在我的测试用例中测试内容的条件部分?

这就是我现在所拥有的:

零件:

function MunicipalityInfo() {
  const [municipalityData, setMunicipalityData] = useState({})

  const fetchData = async () => {
    try{
      const result = await fetch(XMLFile)
      const data = await result.text();
      const xml = new XMLParser().parseFromString(data);
      const res = XMLMapper(xml)
      setMunicipalityData(res)
    }catch(e){
      console.log(e)
    }
  }

  useEffect(() => {
     fetchData();
  }, []);

  return(
    <>
     { municipalityData.units &&
        municipalityData.units.map((city, index) => {
          return (
            <Div key={index} data-testid="municipalityInfo-component" className="mt-5 p-3">
              <HeaderMain data-testid="header-main">{city.City}</HeaderMain>
              <HeaderSub data-testid="header-sub" className="mt-4">{city.venamn}</HeaderSub>
              <BodyText data-testid="body-text">{city.Address}, {city.City}</BodyText>
              <MapLink href={"#"} data-testid="map-link"><i data-testid="map-icon" className="fas fa-map-marker-alt"></i> Show on map</MapLink>
              <LinkList data-testid="link-list">
                <LinkListItem data-testid="list-item-first">
                  <Link href={city.BookingURL} data-testid="link-book-vaccination">Some text</Link>
                </LinkListItem>
              </LinkList>
              <Calendar data={city.unit}/>
            </Div>
          )
        })
      }
      <CitiesSideBar>
        <Sidebar data={municipalityData.cities}/>
      </CitiesSideBar>
    </>
  )
}

export default MunicipalityInfo;

这是我的测试:

describe("<MunicipalityInfo />", () => {
  it("renders without crashing", async  () => {
    const {queryByTestId, findByText, findByTestId} = render(<MunicipalityInfo/>, {})

    expect(queryByTestId("municipalityInfo-component")).not.toBeInTheDocument();
    expect(await findByTestId("municipalityInfo-component")).toBeInTheDocument(); <--- this line fails
  })
})

我的测试用例的错误:

TestingLibraryElementError: Unable to find an element by: [data-testid="municipalityInfo-component"]

标签: reactjsjestjsreact-testing-library

解决方案


如果您的问题是尝试测试页面中是否不应该出现某些内容...

使用queryBy

如果您希望它等待某事......那么您想要await findBy(或包裹在等待中)

这是文档:https ://testing-library.com/docs/react-testing-library/cheatsheet/

我假设你在嘲笑 fetch 请求,所以它不会是测试问题......

如果你不模拟它......那么你可能应该模拟并返回数据或不返回数据来测试它是否应该呈现。

优雅地“避免”模拟的一种方法是将其抽象为自定义钩子:

function useCustomHook(){
  const [municipalityData, setMunicipalityData] = useState({})

  useEffect(() => {
    fetch(XMLData)
    .then((res) => res.text())
    .then(async (data) => {
      let xml = new XMLParser().parseFromString(data);
      let result = await XMLMapper(xml)
      setMunicipalityData(await result)
    })
    .catch((err) => console.log(err));
  }, []);

  return municipalityData;
}
function MunicipalityInfo({municipalityData = useCustomHook()}) { ... }

那么在测试中你可以简单地

render(<MunicipalityInfo municipalityData={'either null or some mocked data'}  />)

推荐阅读