Как протестировать компонент, который не обрабатывает отклоненное обещание, с помощью `wait` из библиотеки activ-testing? - PullRequest
0 голосов
/ 18 января 2019

Типичный интернет-магазин. Я пытаюсь протестировать сценарий, в котором AJAX-запрос не выполняется, когда пользователь пытается разместить заказ. Пользователь также может подписаться на услугу подписки, но запрос на эту подписку должен выполняться только в случае успешного размещения заказа.

Чтобы проверить этот неудачный сценарий, я использую отклонение Обещания, но неперехваченная ошибка всплывает и вызывает сбой теста.

Кто-нибудь знает, как я могу это проверить, желательно без добавления catch к цепочке в методе onSubmit компонента Confirmation? Jest или wait из библиотеки-реакции-тестирования предоставляют альтернативные методы для тестирования этого сценария?

Я понимаю, что Jest предоставляет .rejects , но я не могу понять, как мне следует реструктурировать свой тест, чтобы он работал с wait.

Компонент:

class Confirmation extends React.Component {
  onSubmit() {
    const { createOrder, items, subscribeUser, userId } = this.props;
    createOrder({ items })
      .then(() => subscribeUser(userId));
      // no catch here because I use an error boundary component 
      // at the the top level of the App's component tree 
      // to catch and log all errors to a logging service
  }
  
  render() {
    return (
      <div>
        <input 
          type="submit" 
          onClick={this.onSubmit} 
          value="Confirm Order"
        />
      </div>
    )
  }
}

Тест:

import React from 'react'
import {
  render,
  fireEvent,
  wait
} from 'react-testing-library'

import Confirmation from './Confirmation'

describe('Confirmation', () => {

  it("should not subscribe when the user's order creation fails", () => {
    const props = {
      userId: 12345,
      items: [{
        id: 121,
        qty: 1
      }, {
        id: 122,
        qty: 2
      }],
      createOrder: jest.fn(() => Promise.reject("Order creation failure")),
      subscribeUser: jest.fn(() => {})
    };

    const {
      container
    } = render( 
      <Confirmation { ...props } />
    );

    fireEvent.click(container.querySelector("#confirm-order"));

    return wait(() => {
      expect(props.createOrder).toHaveBeenCalledWith({
        items: props.items
      });
      expect(props.subscribeUser).not.toHaveBeenCalled();
    });
  });

});

Обратите внимание, что приведенные выше фрагменты не являются исполняемыми - в действительности этот компонент немного сложнее, чем в приведенном выше примере, но я постарался максимально упростить его, не искажая проблему.

Редактировать

Обтекание <Confirmation/> в другом компоненте с границей ошибки, похоже, тоже не работает. Ошибка по-прежнему всплывает в дереве компонентов, чтобы не пройти тест:

Jest failure

1 Ответ

0 голосов
/ 18 января 2019

Я бы создал небольшой компонент, который будет отлавливать ошибки и отображать его тоже:

const onError = jest.fn()
class Catcher extends React.Component {
  componentDidCatch(error, info) {
    onError(error, info)
  }

  render() {
    return this.props.children
  }
}

const { container } = render(
  <Catcher>
    <Confirmation { ...props } />
  </Catcher>
);

// After
expect(onError).toHaveBeenCalledTimes(1)
...