API呼び出しのテスト


第2部では、APIからデータを取得し、そのデータをUIでレンダリングするコンポーネントをテストする方法を学びます.
これは簡単です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 スナップショットを更新するには、ユーザーリストに最新の変更を取得します.
読んでくれてありがとう!