API呼び出しのテスト
第2部では、APIからデータを取得し、そのデータをUIでレンダリングするコンポーネントをテストする方法を学びます.
これは簡単です
注意:フックに慣れていない場合は、
これが
今、あなたのテストを孤立させる必要がありますので、実行するたびに、サーバーまたはサードパーティ製のサービスから実際のAPIを呼び出すと、両方の依存性と非効率的な分離原理を満足していないだろう.それで、我々はAPIリクエストを模擬して、我々自身のサンプル反応を返すべきです.
このために、私はreact-mock パッケージは、フェッチ要求をモッキングするための便利なAPIを提供します.
まず、必要なインポートを追加し、返されるサンプルユーザー配列を作成します.
第二に、我々は
注意: APIが返すすべてのフィールドを含んでいませんが、コンポーネントの中でレンダリングされるフィールドのサブセットのみを返します.
最後に、私たちは
最初の行はシンプルで、ユーザーコンポーネントを
行目は、読み込み中のテキストがUIに表示されているかどうかを示します.これは
注意:
番目の行は、我々が使用する場所です
我々のコンポーネントでは、読み込み後のコンテンツは、APIが成功した応答を返すと、ユーザーリストに置き換えられます.So
私たちの模擬APIは成功です.
テストの4番目と最後の行では、リストの長さがモックアップAPIに渡されたサンプルデータの長さに等しいかどうかを確認します.
上の例との対応はhere . それはこのシリーズの前のポストからの例を含みます、そして、更なるユースケースの例も同様に含みます.
注:ケントがコメントで言及したように、我々は、それを確実にするために、我々のテストにもう一つの線を加えることができます
このため、Jestでスナップショットの種類があります.inline snapshots ! 外部スナップショットとは異なり、インラインスナップショットは、外部で作成する代わりにレンダリングされているコンテンツをテストに直接書き込みます
前方に移動し、我々は渡されたサンプルのユーザーリストを変更し、ファイルを保存し、このメソッドに反映される変更に気付きます.
あなたが失敗したテストを得ているならば
読んでくれてありがとう!
これは簡単です
Users
コンポーネント.import React, { useEffect, useState } from 'react'
import { User } from 'types/users'
import { getUsers } from 'services/users'
const Users: React.FC = () => {
let [users, setUsers] = useState<User[]>([])
let [loading, setLoading] = useState(false)
useEffect(() => {
setLoading(true)
getUsers()
.then(users => setUsers(users))
.catch(console.error)
.then(() => setLoading(false))
}, [])
return loading ? (
<p aria-label="loading">Loading ...</p>
) : (
<ul style={{ listStyle: 'none' }}>
{users.map(user => (
<li key={user.id}>
{user.name} ({user.email})
</li>
))}
</ul>
)
}
export default Users
ここではuseEffect
フック、私はgetUsers
方法及び設定loading
and users
APIからデータが受信されるときに基づく状態.それに応じて、ローディングインジケータを設定し、ユーザーがフェッチされた後、リストにユーザーの詳細のカップルをレンダリングします.注意:フックに慣れていない場合は、
useState
通常、クラスコンポーネントおよびuseEffect
メソッドcomponentDidMount
.これが
getUsers
メソッド.export const getUsers = () => {
return fetch('https://jsonplaceholder.typicode.com/users').then(res =>
res.json()
)
}
私は単に使用JSONPlaceholder いくつかの偽ユーザーを取得します.このテストでは、ローディングテキストが表示され、API呼び出しが行われた後、ユーザーが表示されているかどうかを確認します.今、あなたのテストを孤立させる必要がありますので、実行するたびに、サーバーまたはサードパーティ製のサービスから実際のAPIを呼び出すと、両方の依存性と非効率的な分離原理を満足していないだろう.それで、我々はAPIリクエストを模擬して、我々自身のサンプル反応を返すべきです.
このために、私はreact-mock パッケージは、フェッチ要求をモッキングするための便利なAPIを提供します.
まず、必要なインポートを追加し、返されるサンプルユーザー配列を作成します.
import React from 'react'
import { render } from '@testing-library/react'
import { FetchMock } from '@react-mock/fetch'
import Users from './Users'
import { User } from 'types/users'
const users: Partial<User>[] = [
{
id: 1,
name: 'Leanne Graham',
email: '[email protected]',
},
{
id: 2,
name: 'Ervin Howell',
email: '[email protected]',
},
]
注意:レンダリングとは別にインポートされたものに注意してください.waitForElement
. これは、任意の非同期操作後にDOM内に要素が存在する場合にアサートする必要があるメソッドです.第二に、我々は
FetchMock
コンポーネントは、APIをシミュレートします.const renderUsers = () => {
return render(
<FetchMock
matcher="https://jsonplaceholder.typicode.com/users"
response={users}
>
<Users />
</FetchMock>
)
}
ここでは、APIのURLを提供していますmatcher
プロップとresponse
Propは、我々がmokingしているユーザーデータを含んでいます.注意: APIが返すすべてのフィールドを含んでいませんが、コンポーネントの中でレンダリングされるフィールドのサブセットのみを返します.
最後に、私たちは
test
以下のようにブロックする.test(`should render the users list`, async () => {
const { getByLabelText, findByRole } = renderUsers()
expect(getByLabelText('loading')).toBeInTheDocument()
let userList = await findByRole('list')
expect(userList.children.length).toEqual(users.length)
})
現在、それは面白くなるところです.最初の行はシンプルで、ユーザーコンポーネントを
FetchMock
取得するラッパーgetByLabelText
コンポーネント要素のクエリ方法です.行目は、読み込み中のテキストがUIに表示されているかどうかを示します.これは
toBeInTheDocument
を使用してマッチしますaria-label
それは我々が追加しましたp
タグ.注意:
toBeInTheDocument
ネイティブの冗談のマーチャーではなく、ライブラリからですjest-dom . を作成することでこれを使用しますsetupTests.ts
ファイル名src
フォルダと追加import '@testing-library/jest-dom/extend-expect'
. これは自動的に私たちが使用できるDOMマッチャーを追加しますexpect
.番目の行は、我々が使用する場所です
findByRole
リストの取得方法.let userList = await findByRole('list')
使用済みawait
このメソッドは、約束を返し、HTML要素を返すMatcher(役割の形式)を受け入れます.私たちのmock APIが私たちが提供した応答を返すまで、これは指定されたDOM要素を待つでしょうul
我々が我々のユーザーリストを提出したタグ.我々のコンポーネントでは、読み込み後のコンテンツは、APIが成功した応答を返すと、ユーザーリストに置き換えられます.So
findByRole
DOM内の要素が利用可能になるまでチェックし、そうでなければエラーをスローします.私たちの模擬APIは成功です.
findByRole
必須の要素、すなわちul
タグ.テストの4番目と最後の行では、リストの長さがモックアップAPIに渡されたサンプルデータの長さに等しいかどうかを確認します.
expect(userList.children.length).toEqual(users.length)
あなたが走るならばyarn test
or npm test
, あなたのテストが合格して表示されます!先に行くとブラウザでアプリケーションを実行するyarn start
or npm start
そして、短い間のローディング指標を見てください、そして、次に、ユーザーはレンダリングされます.上の例との対応はhere . それはこのシリーズの前のポストからの例を含みます、そして、更なるユースケースの例も同様に含みます.
注:ケントがコメントで言及したように、我々は、それを確実にするために、我々のテストにもう一つの線を加えることができます
ul
は、ユーザーが正しくメールを使用してレンダリングされたユーザーは、私たちのユーザーリストがレンダリングされたとして渡されたものを保証します.このため、Jestでスナップショットの種類があります.inline snapshots ! 外部スナップショットとは異なり、インラインスナップショットは、外部で作成する代わりにレンダリングされているコンテンツをテストに直接書き込みます
.snap
ファイルとそのためには、この行のコードをテストに追加する必要があります.expect(userList.textContent).toMatchInlineSnapshot()
ジェストは自動的にその内容を満たしますul
タグでtoMatchInlineSnapshot
メソッド.ので、テストを保存した後、それはあなたが渡されたリストで更新する必要があります.甘い!前方に移動し、我々は渡されたサンプルのユーザーリストを変更し、ファイルを保存し、このメソッドに反映される変更に気付きます.
あなたが失敗したテストを得ているならば
u
スナップショットを更新するには、ユーザーリストに最新の変更を取得します.読んでくれてありがとう!
Reference
この問題について(API呼び出しのテスト), 我々は、より多くの情報をここで見つけました https://dev.to/ryands17/testing-api-calls-88iテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol