반응에서 클래스 구성 요소를 테스트하는 방법


9

단위 테스트를 시도 중이며 가짜 예제 https://codesandbox.io/s/wizardly-hooks-32w6l (실제로 양식이 있음) 으로 샌드 박스를 만들었습니다.

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { number: 0 };    
  }

  handleSubmit = (number1, number2) => {
    this.setState({ number: this.handleMultiply(number1, number2) })
  }

  handleMultiply = (number1, number2) => {
    return number1 * number2
  }

  render() {
    const { number } = this.state;

    return (
      <div className="App">
        <form onSubmit={e => this.handleSubmit(3, 7)}>       
          <input type="submit" name="Submit" value="Multiply" />
        </form>
        <Table number={number} />
      </div>
    );
  }
}

export default App;

그래서 내 초기 아이디어는 곱하기 함수를 테스트하려고했습니다. 그리고 이것은 분명히 작동하지 않습니다.

import App from "../src/App";

test("Multiply", function() {
  const expected = 21;
  const result = App.handleMultiply(3, 7);
  expect(result).toBe(expected);
});

나는 얻다

_App.default.handleMultiply는 함수가 아닙니다

내 접근 방식이 맞습니까? 그렇다면 기능을 어떻게 테스트합니까? 그렇지 않으면 내부 기능 대신 사용자 관점에서 테스트해야합니까 (이것은 내가 읽은 것입니다)? 화면의 출력을 테스트해야합니까 (이것이 합리적이라고 생각하지 않습니다)?


2
잘못된 사고 방식 으로이 문제에 접근하고 있습니다. 대신 양식 제출을 트리거 한 다음 곱하기 논리를 포함하여 상태가 적절하게 업데이트되었는지 확인하십시오.
— Alexander Staroselsky

@AlexanderStaroselsky 알았어, 고마워, 내가 시도하고, 내가 막히면 더 구체적인 질문을 할 것이다
— user3808307

@AlexanderStaroselsky 자식 구성 요소의 양식과 부모의 제출 핸들러는 어떻게됩니까? 거기에서 통합 테스트를 수행해야합니까?
— user3808307

1
그것은 의견의 문제 일지 모르지만 나는 이것을 별도로 테스트 할 것입니다. 자식에 대한 테스트는 제출시 소품을 통해 부모로부터 전달 된 함수를 트리거 한 다음 상태가 예상대로 렌더링되는지 테스트하는 것입니다. 부모의 경우 이벤트를 트리거하고 상태가 올바르게 업데이트되었는지 확인했습니다.
— Alexander Staroselsky

@AlexanderStaroselsky 감사합니다
— user3808307

답변:


4

instance () 메소드를 사용 enzyme하여 React Component의 인스턴스를 가져올 수 있습니다 . 그런 다음 handleMultiply메소드를 직접 호출 하고 어설 션을 작성하십시오. 또한, handleMultiply메서드에 부작용이 있거나 계산이 매우 복잡한 경우 간단한 모의 반환 값을 만들어야합니다. handleSubmit방법에 대한 격리 된 테스트 환경을 만듭니다. 이것은 handleSubmit메소드가 실제 handleMultiply메소드 구현의 리턴 값에 의존하지 않음을 의미 합니다.

예 :

app.jsx:

import React from 'react';
import { Table } from './table';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { number: 0 };
  }

  handleSubmit = (number1, number2) => {
    this.setState({ number: this.handleMultiply(number1, number2) });
  };

  handleMultiply = (number1, number2) => {
    return number1 * number2;
  };

  render() {
    const { number } = this.state;

    return (
      <div className="App">
        <form onSubmit={(e) => this.handleSubmit(3, 7)}>
          <input type="submit" name="Submit" value="Multiply" />
        </form>
        <Table number={number} />
      </div>
    );
  }
}

export default App;

table.jsx:

import React from 'react';

export const Table = ({ number: num }) => {
  return <div>table: {num}</div>;
};

app.test.jsx:

import App from './app';
import { shallow } from 'enzyme';

describe('59796928', () => {
  let wrapper;
  beforeEach(() => {
    wrapper = shallow(<App></App>);
  });
  describe('#handleSubmit', () => {
    it('should pass', () => {
      expect(wrapper.exists()).toBeTruthy();
      wrapper.find('form').simulate('submit');
      expect(wrapper.state()).toEqual({ number: 21 });
    });
  });
  describe('#handleMultiply', () => {
    it('should pass', () => {
      const comp = wrapper.instance();
      const actual = comp.handleMultiply(2, 10);
      expect(actual).toBe(20);
    });
  });
});

적용 범위 보고서가있는 단위 테스트 결과 :

 PASS  src/stackoverflow/59796928/app.test.jsx (11.688s)
  59796928
    #handleSubmit
      ✓ should pass (16ms)
    #handleMultiply
      ✓ should pass (9ms)

-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |    90.48 |      100 |    85.71 |    94.44 |                   |
 app.jsx   |      100 |      100 |      100 |      100 |                   |
 table.jsx |       50 |      100 |        0 |    66.67 |                 4 |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        13.936s

소스 코드 : https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59796928


양식이 하위 구성 요소에있는 경우 어떻게됩니까? 테스트에서 handleSubmit을 트리거하는 방법과 양식 제출을 사용하는 방법은 무엇입니까? 감사합니다
— user3808307
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.