React 구성 요소 시뮬레이션의 기본 형식

14712 단어 reacttestingjavascript
내가 보기에 왜 비웃는 것이 유용한가.
이 부분에서, 나는 React-mock 구성 요소의 기본 형식을 소개할 것이다.
이 글의 모든 코드 샘플은 아래의 Repo에서 찾을 수 있습니다.

회사 명 / 아날로그 반응 구성 요소


React 구성 요소의 예시를 시뮬레이션하는 방법


사용 중인 구성 요소를 다시 한 번 살펴보겠습니다: BlogPagePostContent.
예:
const getPostIdFromUrl = url =>
  url.substr(url.lastIndexOf("/") + 1)

export const BlogPage = ({ url }) => {

  const id = getPostIdFromUrl(url)

  return (
    <PostContent id={id} />
  )
}
BlogPage 공연 aBlogPage 외에는 아무것도 하지 않았다.그러나 이것은 확실히 우리가 흥미를 느끼는 기능이 하나 있다. 그것은 바로 해석PostContentprop값이 필요한posturl를 끌어내는 것이다.id는 좀 복잡합니다. 브라우저의 내장 PostContent 함수를 호출하여 URLfetch에 있는 블로그 글의 텍스트를 검색합니다. 그 중에서 /post?id=${id} 은 그것에게 전달되는 도구입니다.
export const PostContent = ({ id }) => {
  const [ text, setText ] = useState("")

  useEffect(() => {
    fetchPostContent(id)
  }, [id])

  const fetchPostContent = async () => {
    const result = await fetch(`/post?id=${id}`)
    if (result.ok) {
      setText(await result.text())
    }
  }

  return <p>{text}</p>
}
실제로 id의 역할은 결코 중요하지 않다. 왜냐하면 우리는 다시는 그것을 보지 않기 때문이다.
우리는 테스트 파일PostContent에서 BlogPage을 위한 테스트를 작성할 것이다.이를 위해 우리는 시뮬레이션BlogPage.test.js을 할 것이다. 그러면 우리는 그것의 실현을 걱정할 필요가 없다.
중요한 점은 우리가 PostContent 를 없애면 PostContent 테스트 세트가 BlogPage.test.js 하는 모든 것을 차단할 수 있다는 것이다.
이것은 PostContent의 시뮬레이션입니다.
import { PostContent } from "../src/PostContent"

jest.mock("../src/PostContent", () => ({
  PostContent: jest.fn(() => (
    <div data-testid="PostContent" />
  ))
}))
우리 그것을 분해합시다.
  • 시뮬레이션용PostContent 정의.따라서 적절한 가져오기를 대칭복사해야 합니다.교체할 수 있도록 호출이 끊겼습니다jest.mock.Jest는 새 정의 모듈로 전체 모듈을 교체합니다.이 예에서 우리는 전체 import 파일을 시뮬레이션했다.
  • 시뮬레이션은 모듈 수준에서 진행되기 때문에 시뮬레이션할 모든 구성 요소는 자신의 모듈에 있어야 합니다.
  • ../src/PostContent의 호출에 대한 스파이가 생성됩니다. 언제 호출되었는지, 어떤 파라미터를 사용했는지 기록하는 대상입니다.그리고 우리는 jest.fntoHaveBeenCalled 일치기 테스트 호출을 사용할 수 있다.
  • toHaveBeenCalledWith의 매개 변수는 호출 함수(구성 요소를 나타낼 때)가 되돌아오는 메모리 값을 정의합니다.
  • 존근 실현은 가능한 한 간단해야 한다.React 구성 요소에 대해 이것은 하나jest.fn를 의미합니다. - 의미가 가장 적은 HTML 요소라고 할 수 있습니다!
  • 이것은 확실히 하나의 속성이 있다. 우리는 이 속성을 사용하여 DOM에서 이 특정 요소를 얻을 것이다.
  • React 테스트 라이브러리는 가능한 상황에서 사용하는 것을 반대합니다. div 테스트를 테스트 실행자가 소프트웨어를 사용하는 실제 사용자로 간주하기를 원하기 때문입니다.그러나 모크에 대해 나는 이 지도를 소홀히 했다. 왜냐하면 모크는 정의적으로 기술적인 문제이기 때문이다.
  • data-testid 값은 어셈블리 이름과 일치합니다.이 예에서 이것은 그것이 data-testid 라는 것을 의미한다.이것은 내가 모든 시뮬레이션에서 따르는 표준 관례이다.
  • 이것은 React 구성 요소 시뮬레이션의 기본 형식입니다.나의 90퍼센트 이상의 시뮬레이션은 모두 이렇다.다른 10퍼센트의 사람들은 약간의 보충이 있는데, 우리는 뒤의 댓글에서 볼 수 있다.
    이 시뮬레이션이 있으면 data-testid 테스트를 작성합시다.

    아날로그 구성 요소가 DOM에 있는지 확인


    describe("BlogPage", () => {
      it("renders a PostContent", () => {
        render(<BlogPage url="http://example.com/blog/my-web-page" />)
        expect(screen.queryByTestId("PostContent"))
          .toBeInTheDocument()
      })
    })
    
    이 테스트는 구성 요소 시뮬레이션을 사용할 때 항상 필요한 두 테스트 중 첫 번째입니다.PostContent 현재 DOM에서 BlogPage 값이 screen.queryByTestId인 구성 요소를 검색합니다.
    다시 말하면, 이것은 우리가 data-testid 구성 요소를 확실히 렌더링했는지 확인한다.

    후내용의 책임감 있는 사용


    주의해라, 나는 사용했다PostContent.React 테스트 라이브러리는 두 계정에서 이 함수를 멀리하려고 합니다. 첫째, queryByTestId 을 지원하길 원합니다. 둘째, 앞에서 언급한 바와 같이 테스트 ID로 검색하지 않기를 원합니다.
    사실 테스트 모크는 내가 유일하게 사용한 것 같다queryByTestId.나는 내가 비시뮬레이션 구성 요소에 대한 사용 getBy 을 피할 방법을 찾지 못한 적이 한 번은 생각나지 않는다.그러나 모크에게는 완벽하다. 왜냐하면 우리가 검사해야 할 것은 바로 기술적인 디테일이기 때문이다.사용자는 이 구성 요소를 영원히 보지 못할 것이다. 그것은 단지 우리의 테스트를 위한 것이다.
    우리가 얻은 것은 일치된 방식으로 아날로그 대상을 구축할 수 있다는 것이다. queryBy 우리는 모든 아날로그 대상에 사용할 수 있는 표준 모델이다.

    queryByTestId 및 TestId

    <div data-testid="ComponentName" /> 변체가 원소와 일치하지 않으면 이상을 일으킬 수 있다.내가 보기에, 이것은 전화가 기대의 일부분이 아닐 때만 적합하다.
    하면, 만약, 만약...
    expect(screen.getByTestId("PostContent"))
      .toBeInTheDocument()
    
    렌더링getBy*이 없으면 이 테스트가 실패하고 queryBy* 이상이 발생합니다.기대는 영원히 이루어지지 않는다!
    기대 실패와 이상 유발 사이의 선택을 고려하여 나는 언제든지 기대를 선택할 것이다. 왜냐하면 이것은 테스트 운영자에게 더욱 의미가 있기 때문이다.

    Unit tests, and in particular when TDD style tests, are very often about the presence of elements. For these tests I find the queryBy much more to my liking.


    시뮬레이션이 올바른 아이템을 통과했는지 확인하기


    두 번째 테스트는 정확한 아이템이 통과되었는지 확인해야 한다getBy.
    it("constructs a PostContent with an id prop created from the url", () => {
      const postId = "my-amazing-post"
      render(<BlogPage url={`http://example.com/blog/${postId}`} />)
      expect(PostContent).toHaveBeenCalledWith(
        { id: postId },
        expect.anything())
    })
    
    이것은 표준 Jest 매칭기<PostContent />를 사용하여 우리가 원하는 매개 변수 호출 getByTestId 함수를 사용할 수 있도록 합니다.
    React 실례화 구성 요소를 사용할 때, 이것은 정의된 함수만 호출합니다. 그 중에서props는 대상을 첫 번째 매개 변수로 하고,ref는 두 번째 매개 변수로 합니다.두 번째 파라미터는 통상적으로 중요하지 않다.
    JSX 문장PostContent은 함수 호출toHaveBeenCalledWith을 생성합니다.
    그러나 우리에게는 지금까지 사용하지 않았던 환상의 두 번째 파라미터도 포함되어 있기 때문에 우리는 이 점을 고려해야 한다.

    두 번째 매개변수로 PostContent 사용


    구성 요소에 반응하는 두 번째 매개 변수는 실례 인용입니다. 이것은 보통 우리의 테스트에 중요하지 않기 때문에, 그 값에 관심이 없다는 것을 표시하기 위해 PostContent({ id: "my-amazing-post" }) 을 전달하기를 원합니다.expect.anything 호출에서 벗어나려면 자신의 Jest matcher를 작성하여 전달할 수 있습니다.

    만약 당신이 아이템을 통과하지 못했다면 to Have Been Called With를 사용하세요


    극소수의 경우, 시뮬레이션된 구성 요소는 어떠한 매개 변수도 받아들일 수 없습니다.expect.anything()을(를) 더 간단한 버전으로 사용할 수 있습니다.

    어셈블리 시뮬레이션의 기본 규칙 이해


    우리는 이미 두 개의 테스트와 하나의 시뮬레이션을 작성했다.다음은 우리가 지금까지 발견한 중요한 교훈이다.
  • 당신의 모크는 expect.anything() 스파이를 사용하고 가능한 한 가장 간단한 구성 요소의 메모리 반환 값을 가지고 있어야 합니다. 즉, toHaveBeenCalled
  • 또한 DOM에서 직접 요소를 찾을 수 있도록 toHaveBeenCalled 속성을 설정해야 합니다.
  • 이 속성의 값은 아날로그 구성 요소의 이름입니다.따라서 toHaveBeenCalledWith 분량의 메모리 값은 jest.fn 이다.
  • 시뮬레이션마다 최소 두 개의 테스트가 필요합니다. 첫 번째 테스트는 DOM에 존재하는지 확인하고, 두 번째 테스트는 정확한 도구를 사용하여 호출합니다.
  • 왜 두 번 테스트를 해야 합니까?


    나는 적어도 두 번의 테스트가 필요하다고 이미 여러 차례 언급했다.그런데 이게 왜요?
    DOM의 존재 여부를 확인하는 첫 번째 테스트가 없으면 간단한 함수 호출을 사용하여 두 번째 테스트를 통과할 수 있습니다.
    export const BlogPost = () => {
      PostContent({ id: "my-awesome-post" })
      return null
    }
    
    왜 이렇게 해야 하는지는 완전한 다른 블로그 글의 주제이지만, 여기에는 간단한 버전이 하나 있다. 일반적으로 우리는 함수 호출이 JSX 문장보다 더 간단하다고 생각한다.엄격한 테스트 원칙을 사용할 때, 테스트를 통과하기 위해 가장 간단한 코드를 작성해야 합니다.
    그렇다면 1차 테스트를 했지만 2차 테스트를 하지 않았다면?
    너는 이렇게 할 수 있다.
    export const BlogPost = () => (
      <PostContent />
    )
    
    마찬가지로 이것은 테스트를 통과하게 하는 가장 간단한 생산 코드이다.
    실제 해결 방안을 얻기 위해서는 두 가지 테스트가 필요합니다.
    이것은 단말기 테스트와 단원 테스트 사이의 중요한 차이점이다. 단원 테스트는 방어적이지만 단말기 테스트는 왕왕 그렇지 않다.
    관건: 테스트를 통과하기 위해 가장 간단한 생산 코드를 시종 작성한다.이렇게 하면 모든 장면을 포함하는 테스트 세트를 작성하는 데 도움을 줄 것입니다.
    이것은 시뮬레이션 구성 요소의 기본 지식을 포함한다.다음 부분에서 우리는 이해할 것이다.

    좋은 웹페이지 즐겨찾기