[英]How would I test this using Jest & React Testing library?
I have a component that I would like to test using Jest and React Testing Library .我有一个组件,我想使用Jest和React 测试库进行测试。 When I say test, I'm basically saying that I want to check if the content shows up on the screen.当我说测试时,我基本上是在说我想检查内容是否显示在屏幕上。 However, I'm running into a serious problem because I'm dealing with an async operation that updates the state, so the content is not appearing immediately.但是,我遇到了一个严重的问题,因为我正在处理更新 state 的异步操作,因此内容不会立即出现。 How would I approach this problem?我将如何解决这个问题? A code snippet would be much appreciated.代码片段将不胜感激。
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
const Home = () => {
const [tv, setTv] = useState([]);
const [tvLoading, setTvLoading] = useState(true);
// Go and fetch popular TV shows
const getPopularTv = async () => {
axios.get( ... )
setTv(data);
setTvLoading(false);
};
// This will run once. As soon as the component gets rendered for the 1st time
useEffect(() => {
getPopularTv();
}, []);
let TvData, loading;
const img_path = 'https://image.tmdb.org/t/p/w500/';
// If we have TV shows, set the 'TvData' variable to a pre-defined block of JSX using it.
if (tv && tv.total_results > 0) {
TvData = (
<div className="row animated fadeIn ">
{tv.results.slice(0, 10).map((show) => {
return (
// I WANT TO TEST IF THIS DIV APPEARS ON THE SCREEN
// SO, ON THIS DIV I'M SETTING UP THE 'data-testid'
// HOWEVER THIS IS A ASYNC OPERATION AND THE CONTENT
// WON'T SHOW UP IMMEDIATELY. HOW WOULD I TEST THIS???
<div
data-testid="home-shows" // HERE'S THE ID THAT I WANT TO USE IN MY TEST
className="col s6 m6 l6"
key={show.id}
>
<Link to={'/tvs/' + show.id}>
<img
className="responsive-img z-depth-3 poster tooltipped"
data-tooltip={show.name}
data-position="top"
src={img_path + show.poster_path}
alt={show.name}
/>
</Link>
</div>
);
})}
</div>
);
}
// Set up the 'loading' screen
loading = (
<div className="progress">
<div className="indeterminate"></div>
</div>
);
return (
<div className="container">
{tvLoading ? loading : TvData}
</div>
);
};
export default Home;
I've tried a combination of act
, findByTestId
, waitFor
, etc. But I can't get it to work properly.我尝试了act
、 findByTestId
、 waitFor
等的组合。但我无法让它正常工作。
For example, I tried something like this:例如,我尝试过这样的事情:
it('should display TV shows', async () => {
const { getByText, findByTestId } =
render(
<BrowserRouter>
<Home />
</BrowserRouter>
)
await findByTestId('home-shows')
expect(getByText('More Info')).toBeInTheDocument();
});
My thinking was, if the content appears then it should contain the text of "More Info".我的想法是,如果内容出现,那么它应该包含“更多信息”的文本。 If that's not the case the content is not visible, so the test should fail.如果不是这种情况,则内容不可见,因此测试应该失败。 however, the test fails regards if the content appears or not and I'm getting an error that I should wrap my test inside of an act()
callback.但是,测试失败与内容是否出现有关,并且我收到一个错误,我应该将我的测试包装在act()
回调中。
Thanks to @EstusFlask I came to a breakthrough.感谢@EstusFlask ,我取得了突破。 The solution was to use waitFor
.解决方案是使用waitFor
。 This is how I solved the problem:这就是我解决问题的方法:
it('should display movies', async () => {
render(
<BrowserRouter>
<Home />
</BrowserRouter>
);
const data = await waitFor(() => screen.findByTestId('home-shows'));
expect(data).toBeTruthy();
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.