当测试一个呈现获取的API数据的React组件时,如何在做出任何断言之前最好等待该数据?

问题描述 投票:1回答:1

我有一个简单的“编辑用户”组件,其中包含带有“名字”字段的表单。首次渲染组件时,该字段为空白,直到完成对用户数据的API请求为止。提取数据后,将更新状态并重新渲染组件,这一次将填充“名字”字段。 (要明确,不需要用户交互就可以进行。)

我的测试期望“ First Name”字段正确填充,但当前失败,因为它仅在获取用户信息之前测试了组件的初始渲染。

测试此行为的有效方法是什么,即等到(模拟的)请求完成之后再进行任何断言?

FWIW,我正在使用React 16.12.0。

这里是缩写部分:

import React, { useState, useEffect } from 'react'
import axios from 'axios'

const EditUser = (props) => {
  const [user, setUser] = useState({
    fname: "",
    lname: ""
  })

  const fetchUser = async () => {
    await axios.get(`/api/users/${props.userId}`)
    .then(response => {
      const data = response.data
      const user = {
        fname: data.attributes.fname,
        lname: data.attributes.lname
      }
      setUser(user)
    })
    .catch(error => console.log(error))
  }

  useEffect(() => {
    fetchUser()
  }, [])

  return (
    <div>
      <h2>Edit User</h2>
      <form>
        <div className="form-group">
          <label>First Name</label>
          <input
            name="fname"
            value={user.fname}
          />
        </div>
      </form>
    </div>
  )
}

export default EditUser

和测试:

import React from 'react'
import { mount } from 'enzyme'
import { act } from 'react-dom/test-utils'
import axios from 'axios'
import MockAdapter from 'axios-mock-adapter'
import EditUser from 'packs/editUser'

describe('editUser', () => {
  let wrapper
  const axiosMock = new MockAdapter(axios)

  axiosMock.onGet('/api/users/5').reply(200, {
    id: 5,
    attributes: {
      fname: 'Bradley',
      lname: 'King'
    }
  })

  it('shows the user edit form', async () => {
    await act(async () => {
      wrapper = await mount(<EditUser userId={5} />)
    })

    const firstNameInput = wrapper.find('input[name="fname"]')

    // the following FAILS because the first name input is blank
    // _until_ the user data is fetched and the component is
    // re-rendered with field populated
    expect(firstNameInput.props().value).toEqual('Bradley')
  })
})

谢谢!

reactjs jestjs axios react-hooks enzyme
1个回答
1
投票

由于您期望发生渲染,因此可以使用.update().update()方法到

将酶成分树快照与反应成分树同步。如果外部某物可能正在某处更新组件的状态,则在检查渲染输出之前运行很有用。

wrapper
© www.soinside.com 2019 - 2024. All rights reserved.