자체 React 연결 작성 - TDD 예

에서 나는 명령식 코드를 유용하고 다시 사용할 수 있는 대상에 봉하여 구성 요소를 간단하고 완전하게 설명하는 갈고리를 만드는 방법을 토론했다.
본고에서 나는 더욱 간단한 예시와 더 적은 코드로 같은 개념을 설명했다.아마도 더 중요한 것은 이것이 우리에게 시운전 공간을 제공하고 TDD의 장점을 체험할 수 있다는 것이다.우리 왔어요...
우리가 구축하고 있는 응용 프로그램에서 다양한 글꼴을 시험적으로 사용할 수 있기를 희망한다고 상상해 보세요.적절한 위치에서 보기 전에는 글꼴의 모양을 이해하기 어렵기 때문에 아래와 같이 컨텍스트에서 여러 글꼴을 쉽게 순환하여 사용할 수 있습니다.

테스트 작성


이것은 인위적인 예가 아니라 우리 응용 프로그램의 실제 기능이라고 가정합시다.우리는 우선 React Testing Library를 사용하여 테스트를 작성한다.
// src/Title.spec.js

import Title from './Title'

test('Cycles through a list of fonts when clicked', () => {
  const text = 'Clickable Fonts'
  const { getByText } = render(<Title>{text}</Title>)

  const fontBefore = window.getComputedStyle(getByText(text)).fontFamily

  fireEvent.click(getByText(text))

  const fontAfter = window.getComputedStyle(getByText(text)).fontFamily

  expect(fontBefore).not.toEqual(fontAfter)
})
이 테스트에는 몇 가지 문제가 있습니다. 그 중에서 가장 중요한 문제는 CSS를 테스트하는 것이 좋은 생각이 아니라는 것입니다. 그러나 사용자를 제외하고는 우리 구성 요소가 어떻게 작동할지 아직 알 수 없습니다.클릭할 때 스타일을 바꾸는 것은 하나의 특성이기 때문에 이것은 우리로 하여금 계속 진행하게 할 것이다.
예상대로 우리의 테스트는 실패했다.(빨간색, 녹색, 재구성 맞나요?)

테스트를 통과하다


테스트를 통과하기 위해 Title 구성 요소를 만들고 구글 글꼴을 추가했습니다. Styled-Components 스타일, useState 갈고리를 통해 현재 표시된 글꼴을 추적하고 onClick 프로세서를 통해 글꼴을 변경했습니다.우리는 최종적으로 다음과 같은 결론을 얻었다.
// src/Title.js

function Title({ children }) {
  const [fontIndex, setFontIndex] = React.useState(0)

  const handleChangeFont = () =>
    setFontIndex(fontIndex >= fontList.length - 1 ? 0 : fontIndex + 1)

  const fontList = [
    'Indie Flower',
    'Sacramento',
    'Mansalva',
    'Emilys Candy',
    'Merienda One',
    'Pompiere',
  ]

  const fontFamily = fontList[fontIndex]

  const StyledTitle = styled.h1`
    font-size: 3rem;
    cursor: pointer;
    user-select: none;
    font-family: ${fontFamily};
  `

  return <StyledTitle onClick={handleChangeFont}>{children}</StyledTitle>
}
이것은 우리의 테스트를 통과시켰다. 예.

이 구성 요소의 작업 원리는 CodeSandbox 프레젠테이션에 나와 있습니다.

저희가 더 잘할 수 있어요.


우리는 이 방면에 약간의 문제가 있다.우리는 우리의 구성 요소가 더욱 성명성을 갖추기를 바란다.이것은 현재 사용자가 글꼴을 눌렀을 때 어떻게 글꼴을 바꾸는지 보여 줍니다.
또 하나는 구성 요소에서 CSS를 테스트하는 것이 이상하다는 것이다.하지만 첫 번째 문제는 쉬우니까.
우리는 모든 논리를 우리 자신의 맞춤형 갈고리로 밀어붙일 것이다.
우리의 새 갈고리는 이렇게 보인다.
// src/useClickableFonts.js

const useClickableFonts = fontList => {
  const [fontIndex, setFontIndex] = React.useState(0)

  const handleChangeFont = () =>
    setFontIndex(fontIndex >= fontList.length - 1 ? 0 : fontIndex + 1)

  const fontFamily = fontList[fontIndex]

  return { fontFamily, handleChangeFont }
}
우리의 구성 요소는 다음과 같다.
// src/Title.js

function Title({ children }) {
  const { fontFamily, handleChangeFont } = useClickableFonts([
    'Indie Flower',
    'Sacramento',
    'Mansalva',
    'Emilys Candy',
    'Merienda One',
    'Pompiere',
  ])

  const StyledTitle = styled.h1`
    font-size: 3rem;
    cursor: pointer;
    user-select: none;
    font-family: ${fontFamily};
  `

  return <StyledTitle onClick={handleChangeFont}>{children}</StyledTitle>
}
구성 요소에 글꼴 설명을 보존하고 갈고리에 전달합니다.이것은 우리가 구성 요소가 하고자 하는 일의 일부이기 때문에 모든 가능한 상태를 설명하는 것이 매우 중요하다.우리는 단지 그들에게 그들이 어떻게 이 주에 들어갔는지 알려주고 싶지 않을 뿐이다.
스타일화된 구성 요소 API도 완전하게 성명된 것으로 구성 요소가 실현하는 일부분이다.그것은 줄곧 존재할 것이다.
우리의 테스트는 여전히 통과되었기 때문에, 우리는 우리가 어떤 것도 파괴하지 않았다는 것을 안다.테스트의 안전성 때문에 재구성이 재미있다.

우리의 구성 요소는 여전히 유효합니다: CodeSandbox demo.

바닥글에 글꼴 이름 추가


우리가 끊임없이 그것을 눌렀을 때, 우리는 현재 표시된 글꼴이 어떤 글꼴인지 가장 잘 알고 있다는 것을 깨달았다.그러나 우리는 이러한 정보가 Title 구성 요소에서 멀리 떨어져 있기 때문에 우리가 진행하고 있는 사용자 체험 디자인 테스트를 방해하지 않기를 바란다.이제 우리는 페이지 밑에 있는 것처럼 미묘하게 그것을 보여 준다.
그러나 우리는 어떻게 Title 구성 요소에서 글꼴 정보를 얻고 페이지의 다른 위치에 놓을까요?
물론 정답은 lift state up.다행히도 논리와 상태를 우리 자신의 갈고리로 밀어서 이 임무를 간단하게 합니다. useClickableFonts행을 위로 이동하고 도구를 전달하기만 하면 됩니다.
// src/App.js

function App() {
  const { fontFamily, handleChangeFont } = useClickableFonts([
    'Indie Flower',
    'Sacramento',
    'Mansalva',
    'Emilys Candy',
    'Merienda One',
    'Pompiere',
  ])

  return (
    <>
      <Title fontFamily={fontFamily} handleChangeFont={handleChangeFont}>
        Clickable Fonts
      </Title>
      <Footer>{fontFamily}</Footer>
    </>
  )
}
좋습니다. 우리는 가장 가까운 공동 조상 (이 간단한 예시에서 App 으로 연결하고 도구를 Title 구성 요소에 전달하고 Footer 에 글꼴의 이름을 표시합니다.Title 구성 요소가 순수 확정 구성 요소가 됨:
// src/Title.js

function Title({ fontFamily, handleChangeFont, children }) {
  const StyledTitle = styled.h1`
    font-size: 3rem;
    cursor: pointer;
    user-select: none;
    font-family: ${fontFamily};
  `

  return <StyledTitle onClick={handleChangeFont}>{children}</StyledTitle>
}
이제 우리는 페이지 밑에 글씨체의 이름을 볼 수 있다.계속하여 다음을 클릭합니다.
그러나 우리의 테스트는 지금 실패했다.CodeSandbox demo 및 분열 테스트 참조)

복구 테스트


이것은 우리로 하여금 왜 우리의 테스트에 문제가 생겼는지 이해하게 했다.도구를 직접 사용하지 않고 구성 요소를 업데이트할 때 useClickableFont 갈고리를 업데이트해야 합니다.그러나 이것은 우리가 어떤 논리도 바꾸거나 재구성하지 않았기 때문에 약간 의외이다.
우리의 테스트는 매우 취약하다. 왜냐하면 우리는 잘못된 것을 테스트했기 때문이다.간단하고 선언적인 React 구성 요소가 아니라 글꼴을 변경하는 명령 기어가 유효한지 테스트해야 합니다.React 및 정형 어셈블리의 너트와 볼트는 이미 양호한 테스트를 거쳤습니다.만약 우리가 자신의 논리를 추가하지 않는다면, 우리는 그것들을 자신 있게 사용할 수 있다.
이것은 우리가 세부 사항을 테스트해야 한다는 것을 의미하지 않는다.갈고리를 작성할 때 React 구성 요소가 사용할 API에 추가합니다.우리는 그 새로운 API를 테스트해야 하지만 외부에서 테스트해야 한다.
우리가 진정으로 테스트하고 싶은 것은 우리의 갈고리다.저희가 react-hooks-testing-library 로 할 수 있어요.
우리의 새로운 테스트는 다음과 같다.
// src/useClickableFonts.spec.js

import useClickableFonts from './useClickableFonts'

test('Cycles through a list of fonts', () => {
  const { result } = renderHook(() =>
    useClickableFonts(['Indie Flower', 'Sacramento', 'Mansalva']),
  )

  expect(result.current.fontFamily).toBe('Indie Flower')

  act(() => result.current.handleChangeFont())

  expect(result.current.fontFamily).toBe('Sacramento')

  act(() => result.current.handleChangeFont())

  expect(result.current.fontFamily).toBe('Mansalva')

  act(() => result.current.handleChangeFont())

  expect(result.current.fontFamily).toBe('Indie Flower')
})
사용자가 사용하는 것처럼 외부에서 테스트하고 있습니다.테스트는 연결고리의 사용 방식과 유사해야 한다.이 경우 사용자는 React 구성 요소입니다.우리는 이 새로운 테스트에 대해 자신감을 가질 수 있다. 왜냐하면 테스트는 구성 요소처럼 그것을 사용하기 때문이다.
우리는 처리 프로그램을 호출할 때마다 갈고리가 순서대로 1, 2, 세 번째 글꼴로 되돌아오는 것을 테스트한다.우리는 또 그것이 다시 첫 번째로 순환하는지 테스트했다.
다음은 CodeSandbox의 마지막 구성 요소입니다.

결론


처음에 정확한 디자인이나 정확한 추상을 알기란 항상 쉽지 않다.이것이 바로 useClickableFont 주기 중의 재구성 부분이 이렇게 중요한데 이 절차를 소홀히 하는 것이 코드 퇴화와 기술 채무 증가를 초래하는 원인이다.
일반적으로 코드를 작동하게 하고 코드를 정확하게 하는 임무를 분리하면 자유를 창조할 수 있다.자유가 시작되고 자유가 더 좋은 실현을 발견한다.
우리는 새로운 구성 요소를 테스트하여 최초의 실현을 발견했다.논리를 갈고리에 추출하면 우리의 코드를 더욱 쉽게 변경할 수 있다.그것을 바꾸는 것은 우리가 더욱 좋은 테스트 방법을 찾는 데 도움을 주었다.
우리는 마침내 깨끗한 성명성 구성 요소를 얻었고, 갈고리는 우리에게 명령식 코드를 테스트하고 다시 사용할 수 있는 편리한 인터페이스를 제공했다.

좋은 웹페이지 즐겨찾기