동일한 조롱 구성 요소의 여러 인스턴스 테스트

12177 단어 reacttestingjavascript
이것은 구성 요소 모형으로 React를 테스트하는 시리즈의 4부입니다. 2부에서 우리는 컴포넌트 목의 기본 형태를 살펴봤습니다. 3부에서는 하위 구성 요소에 대한 어설션 기능을 추가했습니다. 이제 우리는 퍼즐의 가장 복잡한 조각인 동일한 모형의 여러 인스턴스를 처리하는 방법을 살펴보겠습니다.


이 게시물의 모든 코드 샘플은 다음 리포지토리에서 사용할 수 있습니다.


dirv / 조롱 반응 구성 요소


React 구성 요소를 조롱하는 방법의 예






새 구성 요소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)
  })
})

그리고 두 번째 테스트를 위해 각기 다른 prop 값을 가진 5개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())
})

그러나 이것에 대해 옳지 않은 것이 있습니다. 렌더링 순서는 테스트하지 않았습니다. 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"
  ])
})
TopFivePostsPage에 대한 처음 두 번의 테스트 후에 이것을 실행하려고 하면 PostContent가 실제로 15번 호출되었다는 이상한 오류가 발생합니다! 각 테스트 사이에 모의 객체를 지워야 하기 때문입니다.

Jest 구성에 clearMocks 속성을 추가하여 이를 수행합니다. 비교를 위해 내 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을 제공할 수 있습니다.
  • 모형을 최대한 단순하게 유지하십시오!

  • 그게 전부입니다. 마지막 부분에서는 모의 객체가 문제를 일으키는 이유와 문제를 피하는 방법을 살펴보겠습니다.

    좋은 웹페이지 즐겨찾기