用笑话来设置反应状态与先前测试的状态

时间:2020-03-14 15:34:17

标签: reactjs jestjs react-testing-library

我正在测试一个组件,如果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一样。

有什么主意我做错了吗?

0 个答案:

没有答案