我正在测试一个组件,如果ajax调用成功完成,它将电影的状态设置为某些数据。如果不是这样的话。
这是进行ajax调用的组件:
class MoviesList extends PureComponent {
state = {
movies: [],
};
async componentDidMount() {
try {
const res = await fetch(
'https://api.themoviedb.org/3/discover/movie?api_key=62a958396506ab41d5e9adf0f55261a3&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1',
)
const movies = await res.json();
if (movies.results) {
this.setState({ movies: movies.results })
}
} catch (e) {
console.error('err: ',e);
}
}
render() {
render() {
if (this.state.movies < 1) return <h1 data-testid="loading">LOADING...</h1>
return (
<MovieGrid data-testid="movie-grid">
{this.state.movies.map(movie => <Movie key={movie.id} movie={movie} />)}
</MovieGrid>
);
}
}
现在,一项测试检查ajax调用是否成功,页面中应该有一个元素,其数据标识为movie-link
:
// use fetch mock
global.fetch = require('jest-fetch-mock')
afterEach(() => {
cleanup
console.error.mockClear()
})
console.error = jest.fn()
const movies = {
success: true,
results: [
{
id: 'hi1',
title: 'title1',
poster_path: 'gfdsftg'
},
{
id: 'hi2',
title: 'title2',
poster_path: 'gfdsftg'
}
]
}
const movie = movies.results[0]
test('<MoviesList />', async () => {
fetch.mockResponseOnce(JSON.stringify(movies))
const {getByTestId, queryByTestId, getAllByTestId} = render(
<MemoryRouter>
<MoviesList />
</MemoryRouter>
)
expect(getByTestId('loading')).toBeTruthy()
await waitForElement(() => getByTestId('movie-link'))
// HERE I TEST TO SE IF movie-link EXISTS!
expect(queryByTestId('loading')).toBeFalsy()
})
如您所见,我正在使用movies
变量来模拟响应。
但是现在我想测试响应是否不成功,元素movie-link
应该不存在。
而且我尝试通过设置movies.results = false
来做到这一点,以免将状态设置为任何值。
这是失败的api测试:
test('<MoviesList /> fail api', async () => {
// HERE
movies.results = false
fetch.mockResponseOnce(JSON.stringify(movies))
console.log('this', movies.results)
const {debug, getByTestId, queryByTestId, getAllByTestId} = render(
<MemoryRouter>
<MoviesList />
</MemoryRouter>
)
expect(getByTestId('loading')).toBeTruthy()
debug()
expect(queryByTestId('movie-link')).toBeFalsy()
})
尽管已设置movies.results = false
,但仍使用movies变量设置状态。而且它不应该像我拥有的组件中一样:
if (movies.results) {
this.setState({ movies: movies.results })
}
因此应将状态设置为结果设置为false。
如果我添加一个调试程序,我可以看到movie-link
以及其他元素都在里面,就好像movies.results = false
是一个包含数据的数组,而不是被设置为false一样。
有什么主意我做错了吗?