前面幾天我們完成了 <Redirect />
元件的基本功能。現在我們需要多加一個測試,這個測試負責驗證:若發送 API 發生錯誤的時候,是否預期顯示錯誤訊息給使用者。
首先,新增一個叫做 'renders an error message from the server'
的測試。使用 mockRejectedValueOnce()
來 mock 錯誤時收到的 data。
tests/post-editor.js
test('renders an error message from the server', async () => {
const testError = 'test error'
mockSavePost.mockRejectedValueOnce({data: {error: testError}})
const fakeUser = userBuilder()
const {getByText} = render(<Editor user={fakeUser} />)
const submitButton = getByText(/submit/i)
fireEvent.click(submitButton)
})
因為我們期望 error 的 dom 會是一個 role=alert
的 div
,因此在測試中使用 findByRole()
來取得這個元素。而且我們要等待這個 promise 被 reject,所以要使用 await findByRole('alert')
來等待。
tests/post-editor.js
test('renders an error message from the server', async () => {
const testError = 'test error'
mockSavePost.mockRejectedValueOnce({data: {error: testError}})
const fakeUser = userBuilder()
const {getByText, findByRole} = render(<Editor user={fakeUser} />)
const submitButton = getByText(/submit/i)
fireEvent.click(submitButton)
const postError = await findByRole('alert')
})
我們加上 assertions。使用 toHaveTextContent()
驗證 alert 的 error message;再使用 .not.toBeDisabled()
驗證 submit button 沒有 disabled。
tests/post-editor.js
test('renders an error message from the server', async () => {
...
expect(postError).toHaveTextContent(testError)
expect(submitButton).not.toBeDisabled()
})
目前,測試是 fail ❌。
我們現在回到 post-editor.js
,補上顯示 error message 的功能。
加上一個新的 error
state,我們希望 error 有值的時候,render <div role="alert">{error}</div>
。
post-editor.js
const [error, setError] = React.useState(null)
function Editor({user}) {
...
return (
<form onSubmit={handleSubmit}>
<label htmlFor="title-input">Title</label>
<input id="title-input" name="title" />
<label htmlFor="content-input">Content</label>
<textarea id="content-input" name="content" />
<label htmlFor="tags-input">Tags</label>
<input id="tags-input" name="tags" />
<button type="submit" disabled={isSaving}>
Submit
</button>
{error ? <div role="alert">{error}</div> : null}
</form>
)
}
現在我們要爲 savePost()
的 .then()
加上第二個參數 response => {}
。裡面我們 handle 收到 error message 的情況,加上 setIsSaving(false)
及 setError(response.data.error)
,設置 button disabled 的狀態及 error message 的狀態。
post-editor.js
function handleSubmit(e) {
e.preventDefault()
const {title, content, tags} = e.target.elements
const newPost = {
title: title.value,
content: content.value,
tags: tags.value.split(',').map(t => t.trim()),
authorId: user.id,
}
setIsSaving(true)
savePost(newPost).then(
() => setRedirect(true),
response => {
setIsSaving(false)
setError(response.data.error)
},
)
}
現在,測試又亮起了綠燈 ✅。