我有一个简单的“编辑用户”组件,其中包含带有“名字”字段的表单。首次渲染组件时,该字段为空白,直到完成对用户数据的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')
})
})
谢谢!