【问题标题】:ReactJS - Test conditional rendering in componentReactJS - 在组件中测试条件渲染
【发布时间】:2021-07-05 15:08:36
【问题描述】:

我有一个使用 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"]

【问题讨论】:

  • 如果您期望页面中可能没有的内容,您应该使用queryByTestId
  • 但是当 useEffect 完成时,我希望文档中有一些内容

标签: reactjs jestjs react-testing-library


【解决方案1】:

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

使用queryBy

如果你想让它等待某事......那么你想await findBy(或换成一个waitFor)

这是文档: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'}  />)

【讨论】:

  • 我已经更新了我的测试用例,我最后一次失败的期望是这样的:expect(await findByTestId("municipalityInfo-component")).toBeInTheDocument();但它仍然失败......
  • 是的!我可以记录数据并查看它
  • 它应该可以工作...我会尝试console.log(municipalityData) 看看是否在测试中记录了一些东西...它应该首先记录默认值,然后是获取的值...
  • 好吧,在浏览器控制台中,我首先得到一个空对象,2 秒后,我得到带有数据的填充对象。在测试中只得到一个空对象。现在我也得到错误:错误:在我的测试用例中连接 ECONNREFUSED 127.0.0.1:80。
  • 测试环境有所不同...您是从后端获取的吗?如果你是,你可能应该模拟/窥探它。
猜你喜欢
  • 2019-01-28
  • 1970-01-01
  • 2019-04-25
  • 2021-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多