同じ模擬コンポーネントの複数のインスタンスのテスト


これは、コンポーネントの塊と反応するテストのシリーズの一部です.パート2では、コンポーネントの塊の基本的な形を見ました.パート3では、コンポーネントの子をアサートする能力を追加しました.今、我々はパズルの最も複雑な部分を見てみます:同じモックの複数のインスタンスを扱う.
このポストのすべてのコードサンプルは、以下のレポで利用できます.

dirv / コンポーネントをmocking反応


コンポーネントをモックアップする方法の例


新しいコンポーネントを続けましょう.TopFivePostsPage , これはおそらく驚異的にトップ5つのポストを示しています.
import { PostContent } from "./PostContent"

export const TopFivePostsPage = () => (
  <ol>
    <PostContent id="top1" />
    <PostContent id="top2" />
    <PostContent id="top3" />
    <PostContent id="top4" />
    <PostContent id="top5" />
  </ol>
);
テストするにはqueryAllByTestId と組み合わせてtoHaveLength マーチャー.
describe("BlogPage", () => {
  it("renders five PostContent components", () => {
    render(<TopFivePostsPage />)
    expect(screen.queryAllByTestId("PostContent"))
      .toHaveLength(5)
  })
})
そして、2回目のテストのためにexpect ステートメントそれぞれ異なるプロップ値を持ちます.
it("constructs a PostContent for each top 5 entry", () => {
  render(<TopFivePostsPage />)
  expect(PostContent).toHaveBeenCalledWith(
    { id: "top1" }, expect.anything())
  expect(PostContent).toHaveBeenCalledWith(
    { id: "top2" }, expect.anything())
  expect(PostContent).toHaveBeenCalledWith(
    { id: "top3" }, expect.anything())
  expect(PostContent).toHaveBeenCalledWith(
    { id: "top4" }, expect.anything())
  expect(PostContent).toHaveBeenCalledWith(
    { id: "top5" }, expect.anything())
})
しかし、これについて全く正しくない何かが、あります.レンダリングの順序をテストしていません.The toHaveBeenCalledWith マッチは気にしない.
私たちは.mock.calls 代わりに.
it("renders PostContent items in the right order", () => {
  render(<TopFivePostsPage />)
  const postContentIds = PostContent.mock.calls.map(
    args => args[0].id)

  expect(postContentIds).toEqual([
    "top1", "top2", "top3", "top4", "top5"
  ])
})
最初の2つのテストの後に実行してみてくださいTopFivePostsPage , あなたは奇妙なエラーを得るでしょうPostContent 実際に15回と呼ばれていた!それは私たちが各テストの間の模擬をクリアする必要があるためです.
我々はそれを追加することによってclearMocks JEST設定へのプロパティー.はい、こちらpackage.json 比較のために.
"jest": {
  "transform": {
    "^.+\\.jsx?$": "babel-jest"
  },
  "setupFilesAfterEnv": ["./jest.setup.js"],
  "clearMocks": true
}
注意:前回のテストで実際に書いた最後のテストでは、前のテストが冗長になります.

十分でないとき:模擬インスタンスID


非常に時折、あなたはこれ以上必要があります.たとえば、渡された子をテストする必要がある場合、複数のインスタンスもあります.その場合、コンポーネントの小道具を使用して、コンポーネントのインスタンスに一意のテストIDを与えることができます.
jest.mock("../src/PostContent", () => ({
  PostContent: jest.fn(({ children, id }) => (
    <div data-testid={`PostContent-${id}`}>
      {children}
    </div>
  ))
}))
個人的に、私は本当にこれが嫌いです.それは複雑で、より複雑であるより複雑です.しかし、それが存在し、時々それを使用する必要があります.
モックは、あなたのテストをスピードアップするためにそこにあることを覚えて、テストはあなたの開発をスピードアップするためにあります.モックが過度に複雑になるとき、あなたは彼らを読んで、彼らを維持するより多くの時間を費やさなければなりません.次の部分でこれ以上カバーします.

より多くのレッスン


それで、我々は現在何を学びましたか?
  • 用途queryAllByTestId 模擬コンポーネントの複数のインスタンスをテストする場合
  • 用途.mock.calls 呼び出しの順序をチェックするか、またはテスト小道具をテストするために.
  • Jestの使用clearMocks 設定は、あなたのスパイは、各テストの前にクリアされるように設定します.
  • 他のすべてが失敗した場合は、レンダリングされた出力内の小道具を使用してdata-testid 各インスタンスの値.
  • あなたのmockをできるだけ簡単にしてください!
  • それはすべてそこにある.最終的な部分では、なぜ私たちはなぜあなたがトラブルにどのようにそれを避けるためにモックを得ることができます.