Как я могу протестировать пользовательский обратный вызов, используемый с сторонним API? - PullRequest
3 голосов
/ 06 мая 2019

Упрощенная настройка моего кода выглядит следующим образом:

App.js

class App extends React.Component {
  componentDidMount() {
    const { thirdPartyAPI } = this.props;
    thirdPartyAPI.field.onValueChanged(this.handleValueChange);
  }

  handleValueChange = (value) => {
    // callback to do complex validation stuff and suchlike
    // update state
  }

  render() {
    // display stuff
  }
}

App.test.js

each([...]).
  .test('App is rendered according to...',
    async (...) => {

    const mockApi = {
      field: {
        onValueChanged: ????
      }
    }

    const AppComponent = await shallow(
      <App thirdPartyAPI={mockApi} />,
    );
  });

OnValueChanged обнаруживает, когда пользователь изменил значение за пределами реагирующего приложения.С точки зрения пользователя это работает, но шутник доставляет мне неприятности.

Проще говоря: как мне это проверить?

Мне нужно смоделировать функцию API, но мне нужно использовать функцию обратного вызова handleValueChange, как определено в App.js,Я потерял из виду шутливые учебники, которые я читал и смотрел, многие из них очень подробные, но ни одна из них, похоже, не относится к данной конкретной ситуации.

Возможно ли вообще протестировать этот код?Если так, то как?А если нет, то как мне реструктурировать свой код, чтобы я смог проверить его?

Если кто-нибудь может указать мне правильное направление, я был бы признателен.

1 Ответ

1 голос
/ 06 мая 2019

Если вы передадите фиктивную функцию вашему компоненту как thirdPartyAPI.field.onValueChanged, то он будет вызываться с this.handleValueChange.

Имитирующие функции записывают все, что они вызывали, поэтому вы можете затем использовать фиктивную функцию дляполучить this.handleValueChange, используя mockFn.mock.calls.

После того, как вы получили this.handleValueChange в своем тесте, вы можете вызвать его напрямую и убедиться, что он работает должным образом.

Вот простой рабочий пример:

import * as React from 'react';
import { shallow } from 'enzyme';

class App extends React.Component {
  constructor(...args) {
    super(...args);
    this.state = { val: 'original' };
  }

  componentDidMount() {
    const { thirdPartyAPI } = this.props;
    thirdPartyAPI.field.onValueChanged(this.handleValueChange);
  }

  handleValueChange = (value) => {
    this.setState({ val: value });
  }

  render() { return null; }
}

test('App', () => {
  const onValueChangedMock = jest.fn();
  const thirdPartyAPIMock = { field: { onValueChanged: onValueChangedMock } };

  const wrapper = shallow(<App thirdPartyAPI={thirdPartyAPIMock} />);
  expect(wrapper.state('val')).toBe('original');  // Success!

  const handleValueChange = onValueChangedMock.mock.calls[0][0];  // <= get handleValueChange...
  handleValueChange('updated');  // <= ...now call it directly

  expect(wrapper.state('val')).toBe('updated');  // Success!
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...