React 구성 요소의 DOM 유닛 테스트

38525 단어 ReactJesttech
React 구성 요소의 DOM 구조를 자동으로 테스트하는 경우 일반적으로 스냅샷 테스트가 수행됩니다.
캡처 테스트는 구조에 변화가 있으면 경고하는 구조로 그 내용은 별로 신경 쓰지 않는다.
그러나 특정 상황에 따라 DOM 구조 자체의 사례를 어떻게든 보증해야 할 때 DOM 구조에 대한 단원 테스트를 하려고 했으나 그렇게 한 사례를 발견하지 못해 기사를 썼다.

캡처 테스트


그러면 본 문제 테스트를 기술하기 전에 React 구성 요소의 스냅샷 테스트를 복습해 보십시오.
import React from 'react'
import { create } from 'react-test-renderer'

test('hoge-', () => {
  const tree = create(<div>ほげー</div>).toJSON()
  expect(tree).toMatchSnapshot()
})
자세한 내용은 Jest 공식 Snapshot Testing · Jest을 참조하십시오.

단원 테스트


그럼 이거 단원 테스트 하나요?
test('hoge-', () => {
  const tree = create(<div>ほげー</div>).toJSON()
  expect(tree).toEqual(<div>ほげー</div>)
})
    Expected: <div>ほげー</div>
    Received: <div>ほげー</div>
의 바람이 되었지만, 외관이 어떻게 다른지 모르겠다.글쎄, JSXElement과 수수께끼의 대상은 아마 다르겠지.비교해 보면 모두 함정으로 보인다.
test('hoge-', () => {
  const tree = create(<div>ほげー</div>).toJSON()
  expect(tree).toEqual(create(<div>ほげー</div>).toJSON())
})
면 어때요?둘 다react-test-renderer 쓰면 같은 물건일 거예요.사실 이것은 성공한 것이다.
그렇다면 이 자아인용 테스트는 그거다. 진실에 더 가까워지기 위해 테스트를 한다.
const Hoge = () => {
  return <div>ほげー</div>
}

test('hoge-', () => {
  const tree = create(<Hoge />).toJSON()
  expect(tree).toEqual(create(<div>ほげー</div>).toJSON())
})
네.구성 요소가 녹아도 문제 없이 테스트를 통과할 수 있다.

처리를 포함한 테스트 수행


그러면 단원 테스트를 할 수 있기 때문에 이벤트 처리를 테스트하는 구성 요소입니다.
const Hoge = ({ onChange, value }) => {
  return <input type="text" onChange={onChange} value={value} />
}

test('hoge-', () => {
  const handleChange = () => {}
  const tree = create(<Hoge onChange={handleChange} value="hoge" />).toJSON()
  expect(tree).toEqual(
    create(<input type="text" onChange={() => {}} value="hoge" />).toJSON()
  )
})
이 코드는 오류가 발생할 수 있습니다.
-   onChange={[Function onChange]}
+   onChange={[Function handleChange]}
지원, 작음.
test('hoge-', () => {
  const handleChange = () => {}
  const tree = create(<Hoge onChange={handleChange} value="hoge" />).toJSON()
  expect(tree).toEqual(
    create(<input type="text" onChange={handleChange} value="hoge" />).toJSON()
  )
})
이렇게 하면 착오가 생기지 않는다.
그럼 Hoge 구성 요소에서 스스로 처리 프로그램을 설정하는 상황은 어떻습니까?
const Hoge = ({ onChange, value }) => {
  const handleChange = React.useCallback(
    ev => {
      onChange(ev.target.value)
    },
    [onChange]
  )
  return <input type="text" onChange={handleChange} value={value} />
}

test('hoge-', () => {
  const handleChange = () => {}
  const tree = create(<Hoge onChange={handleChange} value="hoge" />).toJSON()
  expect(tree).toEqual(
    create(<input type="text" onChange={handleChange} value="hoge" />).toJSON()
  )
})
이것은 잘못된 것이다.
-   onChange={[Function handleChange]}
+   onChange={[Function anonymous]}
가늘다!!!
그럼 이름만 모으면 되나요?
test('hoge-', () => {
  const anonymous = () => {}
  const tree = create(<Hoge onChange={anonymous} value="hoge" />).toJSON()
  expect(tree).toEqual(
    create(<input type="text" onChange={anonymous} value="hoge" />).toJSON()
  )
})
안 돼요.
Expected: <input onChange={[Function anonymous]} type="text" value="hoge" />
Received: <input onChange={[Function anonymous]} type="text" value="hoge" />
상대를 비교하고 계시죠.이름은 같지만 생성은 다르다.
그렇다면 지금의 방법은 테스트할 수 없다.
그런데 아까 스냅숏 테스트가 끝난 Snapshot을 봤어요.
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`hoge- 1`] = `
<input
  onChange={[Function]}
  type="text"
  value="hoge"
/>
`;
온체인지의 내용이 [Function]로 바뀌었잖아요.뭐, 제스트 호스트를 열심히 쫓는 것도 그것 때문이야, 더 빠른 수단으로 하소연하는 거야.
test('hoge-', () => {
  const anonymous = () => {}
  const tree = JSON.stringify(
    create(<Hoge onChange={anonymous} value="hoge" />).toJSON()
  )
  expect(tree).toEqual(
    JSON.stringify(
      create(<input type="text" onChange={anonymous} value="hoge" />).toJSON()
    )
  )
})
비교JSON.stringify 후 이벤트 처리 프로그램의 호출 대상의 차이는 무시됩니다.
그럼 오류가 발생했을 때 어떻게 표시됩니까?
  expect(tree).toEqual(
    JSON.stringify(
      create(<input type="text" onChange={anonymous} value="fuga" />).toJSON()
    )
  )
이렇게 일부분을 고쳐 썼는데 오류가 났어요.
- {"type":"input","props":{"type":"text","value":"fuga"},"children":null}
+ {"type":"input","props":{"type":"text","value":"hoge"},"children":null}
정말 어려워!
적어도 조금만 더 알기 쉽게.JSON.stringify 세 번째 매개변수를 추가하면 들여쓰기가 양호합니다.
test('hoge-', () => {
  const anonymous = () => {}
  const tree = JSON.stringify(
    create(<Hoge onChange={anonymous} value="hoge" />).toJSON(),
    null,
    '  '
  )
  expect(tree).toEqual(
    JSON.stringify(
      create(<input type="text" onChange={anonymous} value="fuga" />).toJSON(),
      null,
      '  '
    )
  )
})
이 경우
  ● hoge-

    expect(received).toEqual(expected)

    Difference:

    - Expected
    + Received

      {
        "type": "input",
        "props": {
          "type": "text",
    -     "value": "fuga"
    +     "value": "hoge"
        },
        "children": null
      }
오류가 발생했습니다.JSX가 비교할 수 있는 게 아니어서 아직 이해하기 어렵지만 value는 아직 다르다는 걸 알아요.
이 어려운 점은 JSX 트리가 어떤 JSON인가요?이해해야 할 것도 있지만 그래도 허용할 수 있는 범위라고 생각해요.
말하자면 리액션 부품의 DOM 구조는 단원 테스트를 할 때 보기 드문 상황이기 때문에 더 많은 노동력을 소모하면 공사를 초과할 것이다.

총결산


React 구성 요소에 대한 단원 테스트를 진행할 때 호출react-test-renderer을 고려하면 비교JSON.stringify의 결과가 비교적 좋다. JSON.stringify(object, null, ' ')처럼 미리 지정하면 알기 쉬운 diff를 얻을 수 있다.

좋은 웹페이지 즐겨찾기