Как проверить асинхронные / ожидающие вызовы API и обновить состояние React - PullRequest
1 голос
/ 13 июня 2019

Я хочу протестировать событие асинхронного щелчка в React, которое выполняет две вещи: 1. Выполните вызов API для отправки запроса POST. 2. После успешного выполнения запроса на публикацию обновите состояние в компоненте верхнего уровня.

Я хочу знать, как лучше всего проверить, что события произошли в этом порядке.

Мне удалось использовать jest-fetch-mock для имитации вызова API. Но я не уверен, как проверить, выполняется ли обновление состояния после API. Более того, обновление состояния - это функция, передаваемая из компонента верхнего уровня в этот дочерний компонент.

В Feedback.jsx updateMembershipStatus передается из другого компонента, называемого ManageMembership.

// This component saves feedback
class Feedback extends PureComponent {
  // ...

  async handleSubmit (event) {
    event.preventDefault();

    const {otherReason} = this.state,
      {id, updateMembershipStatus} = this.props;

    try {
      // 1. Make an API call
      const saveReason = await MembershipStatusAPI.updateOtherCancelReason(id, otherReason);
      // 2. Update membership status
      updateMembershipStatus("Feedback");
    } catch (error) {
      console.error("Oops, handleSubmit failed!", error);
    }
  }

  render () {
    const {isDisabled, otherReason} = this.state;
    return (
      <div>
        <div>
          Please let us know your feedback
        </div>
        <textarea
          className="feedback-input"
          onChange={this.handleChange}
          value={otherReason}
        />
        <button
          disabled={isDisabled}
          onClick={(e) => this.handleSubmit(e)}
          type="submit"
          value="Submit"
        >
          Cancel my membership
        </button>
      </div>
    );
  }
}

ManageMembership.jsx является компонентом верхнего уровня

class MembershipManagement extends PureComponent {
  // ... 
  constructor (props) {
    super(props);
    this.state = {
      "membershipStatus": this.getCurrentStatus(),
    };
  }

  updateMembershipStatus = (event) => {
    if (event === "Feedback") {
      this.setState({"membershipStatus": "Pending Cancellation"});
    }
  }
}

Мой тест, FeedbackTest.jsx

describe("<Feedback /> button", () => {
  let handleSubmit = null,
    wrapper = null;

  const updateOtherCancelReason = (url) => {
    if (url === "google") {
      return fetch("https://www.google.com").then(res => res.json());
    }
    return "no argument provided";
  };

  beforeEach(() => {
    handleSubmit = jest.fn();
    wrapper = mount(
      <Feedback
        disabled
        id={1234567}
      />
    );
    fetch.resetMocks();
  });

    it("should trigger handleSubmit asynchronously: it should call updateOtherCancelReason API first to save comments, then update state", async () => {
    fetch.mockResponseOnce(JSON.stringify({"other_reason": "I am moving to Mars."}));

    wrapper.find("button").simulate("click");

    const callAPI = await updateOtherCancelReason("google");
    expect(callAPI.other_reason).toEqual("I am moving to Mars.");

    expect(fetch.mock.calls.length).toEqual(1);

    // How to test async code here?
  });

Этот тест выше пройден, потому что я использовал jest-fetch-mock для имитации вызова API, который дает нам ложный ответ. Как я могу проверить, вызван ли updateMembershipStatus и успешно ли он обновил состояние до «Ожидает отмены» в ManageMembership.jsx?

Еще один похожий пост: Тестирование API Call in React - Состояние не обновляется , однако никто не ответил на него.

1 Ответ

0 голосов
/ 13 июня 2019

Я бы использовал для этого реагирующую библиотеку.Если в результате какого-либо асинхронного действия на экране появляется какой-либо элемент, мы можем проверить его следующим образом:

await wait(() => getByText(container, 'some-item'))
// make asserts
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...