Як перевірити компоненти класу в реакції


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
Ви до цього підходите неправильно. Замість цього запустіть форму надсилання, потім перевірте, чи переконалося, що стан було оновлено належним чином, включаючи логіку множення.
Олександр Старосельський

@AlexanderStaroselsky ок, спасибі, я спробую, і поставлю більш конкретний питання, якщо я застряг
user3808307

@AlexanderStaroselsky що робити, якщо форма у дочірньому компоненті та обробники подання у батьків? Чи потрібно робити там інтеграційні тести?
користувач3808307

1
Це може бути питанням думки, але я обов'язково перевіряю їх окремо. Тести для дитини полягають у тому, що при подачі він запускає функцію, передану від батьків через реквізит, а також перевіряє, що стан видає так, як ви очікували. Для батьків я б запустив подію і переконався, що стан було оновлено правильно.
Олександр Старосельський

@AlexanderStaroselsky Дякую
користувач3808307

Відповіді:


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 у тесті, крім того, що подає форму? Дякую
користувач3808307
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.