我将如何使用 Jest 和 React 测试库对此进行测试?
How would I test this using Jest & React Testing library?
我有一个组件,我想使用 Jest 和 React 测试库 进行测试。当我说测试时,我基本上是说我想检查内容是否显示在屏幕上。但是,我 运行 遇到了一个严重的问题,因为我正在处理更新状态的异步操作,因此内容不会立即出现。我将如何解决这个问题?代码片段将不胜感激。
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;
我尝试了 act
、findByTestId
、waitFor
等组合。但我无法正常工作。
例如,我试过这样的事情:
it('should display TV shows', async () => {
const { getByText, findByTestId } =
render(
<BrowserRouter>
<Home />
</BrowserRouter>
)
await findByTestId('home-shows')
expect(getByText('More Info')).toBeInTheDocument();
});
我的想法是,如果内容出现,那么它应该包含“更多信息”的文本。如果不是这种情况,则内容不可见,因此测试应该会失败。但是,测试失败与内容是否出现有关,我收到一个错误,我应该将我的测试包装在 act()
回调中。
感谢 @EstusFlask 我取得了突破。解决方案是使用 waitFor
。
我就是这样解决问题的:
it('should display movies', async () => {
render(
<BrowserRouter>
<Home />
</BrowserRouter>
);
const data = await waitFor(() => screen.findByTestId('home-shows'));
expect(data).toBeTruthy();
});
我有一个组件,我想使用 Jest 和 React 测试库 进行测试。当我说测试时,我基本上是说我想检查内容是否显示在屏幕上。但是,我 运行 遇到了一个严重的问题,因为我正在处理更新状态的异步操作,因此内容不会立即出现。我将如何解决这个问题?代码片段将不胜感激。
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;
我尝试了 act
、findByTestId
、waitFor
等组合。但我无法正常工作。
例如,我试过这样的事情:
it('should display TV shows', async () => {
const { getByText, findByTestId } =
render(
<BrowserRouter>
<Home />
</BrowserRouter>
)
await findByTestId('home-shows')
expect(getByText('More Info')).toBeInTheDocument();
});
我的想法是,如果内容出现,那么它应该包含“更多信息”的文本。如果不是这种情况,则内容不可见,因此测试应该会失败。但是,测试失败与内容是否出现有关,我收到一个错误,我应该将我的测试包装在 act()
回调中。
感谢 @EstusFlask 我取得了突破。解决方案是使用 waitFor
。
我就是这样解决问题的:
it('should display movies', async () => {
render(
<BrowserRouter>
<Home />
</BrowserRouter>
);
const data = await waitFor(() => screen.findByTestId('home-shows'));
expect(data).toBeTruthy();
});