Как протестировать функциональный компонент React, который загружает данные во время монтирования - PullRequest
0 голосов
/ 10 апреля 2020

Я хочу провести разные модульные тесты для проверки разных состояний моего компонента и его взаимодействия с асинхронным c запросом. У меня много трудностей с этим. В большинстве документов говорится, что «имитировать» событие, которое вызывает асинхронное изменение состояния c (то есть имитировать щелчок компонента), однако мое состояние должно меняться при загрузке компонента, а не в результате какого-либо взаимодействия с пользователем. Я видел ссылку на функцию act (https://reactjs.org/blog/2019/02/06/react-v16.8.0.html#testing -hooks ), но я не знаю, как реализовать ее в этом контексте.

Вот мой функциональный компонент реакции:

import { useRequest } from '@umijs/hooks' // Request custom hook

// An async function that does an async task to get data
async function someAsyncFunctionToFetch() => {
    return Promise.resolve({data: 'data'})
}

// The functional component
export function TestComponent() {
  const { data, error, loading } = useRequest(FulfillmentService.getFullfillmentServices)

  const loadingMarkup = (
    <p>Loading</p>
  )

  const errorMarkup = (
    <p>Error</p>
  )

  const contentMarkup = (
    <p>{ data }</p>
  )

  if (loading) {
    return loadingMarkup
  } else if (error) {
    return errorMarkup
  } else if (!isEmpty(data)) {
    return contentMarkup
  } else {
    return <p>Some empty state</p>
  }
}

Вот тесты, которые я хочу выполнить:

describe('TestComponent', () => {
    it.todo('when data is loading the loading markup should be rendered')
    it.todo('when data fetching results in an error the error markup should be rendered')
    it.todo('when data fetching returns with valid data the content markup should be rendered')
    it.todo('when data fetching returns an empty data object the empty state markup should be rendered')
})

Ответы [ 2 ]

0 голосов
/ 11 апреля 2020

Чтобы проверить, визуализирует ли компонент нужную разметку для каждого состояния, вы можете смоделировать возвращаемое значение хука useRequest. Это может быть достигнуто с помощью функции jest.mock для проверки поведения модуля @umijs/hooks:

import { useRequest } from "@umijs/hooks";

jest.mock("@umijs/hooks");

Теперь каждое состояние можно моделировать с помощью mockReturnValue функция. Например, чтобы смоделировать состояние загрузки, мы сделаем:

useRequest.mockReturnValue({ 
  loading: true 
});

Тесты для каждого сценария будут выглядеть примерно так:

import { useRequest } from "@umijs/hooks";

jest.mock("@umijs/hooks");

describe("TestComponent", () => {
  describe("loading description", () => {
    beforeEach(() => useRequest.mockReturnValue({ loading: true }));

    it("loading assertion", () => {/* ... */});
  });

  describe("error description", () => {
    beforeEach(() => useRequest.mockReturnValue({ error: "Given error" }));

    it("error assertion", () => {/* ... */});
  });

  describe("valid data description", () => {
    beforeEach(() => {
      useRequest.mockReturnValue({ data: { value: "Given data" }});
    });

    it("valid data assertion", () => {/* ... */});
  });

  describe("empty data description", () => {
    beforeEach(() => useRequest.mockReturnValue({ data: {} }));

    it("empty data assertion", () => {/* ... */});
  });
});
0 голосов
/ 11 апреля 2020

Я бы рекомендовал попытаться абстрагироваться от FulfillmentService.getFullfillmentServices, переместив его в props или создать контекст. Таким образом, вы можете легко высмеивать каждый ответ от FulfillmentService.getFullfillmentServices.

Второй вариант - использовать nock и перехватывать вызов API FulfillmentService.getFullfillmentServices.

...