Как смоделировать и протестировать запрос ApolloClient graphql - PullRequest
0 голосов
/ 03 февраля 2020

Я пытаюсь смоделировать и протестировать вызов API, выполненный с помощью ApolloClient в React, с использованием Jest и реагировать на тестирование библиотеки. Но похоже, что вызов никогда не происходит.

Код распределен по трем файлам в одном каталоге / sr c:

/ src / apolloClient. js содержит клиента instance:

import ApolloClient from "apollo-boost";

export const client = new ApolloClient({
    uri: "https://api.github.com/graphql",
    headers: {
      authorization: `Bearer ${process.env.REACT_APP_GITHUB_ACCESS_TOKEN}`
    }
  });

query. js содержит запрос graphql и функцию, которая делает вызов:

import { gql } from "apollo-boost";
import { client } from "../apolloClient";

export const userQuery = gql`
  query($login: String!) {
    user(login: $login) {
      name
      email
      ...
    }
  }
`;

export const getGitHubProfile = (userLogin, setUser) =>
  client
    .query({ query: userQuery, variables: { login: userLogin } })
    .then(response => setUser(response.data.user))
    .catch(err => console.log(err));

Landing. js содержит форму, которая делает вызов:

import React, { useState } from "react";
import { getGitHubProfile } from "./query";
import CV from "./CV";

function Landing() {
  const [userLogin, setUserLogin] = useState("");
  const [user, setUser] = useState();

  const submitUserLogin = async e => {
    e.preventDefault();
    userLogin && getGitHubProfile(userLogin, setUser); // Called here on submit.
  };

  const gitHubUsernameForm = () => {
    return (
          ...
          <form
            data-testid="form"
            className="form field has-addons"
            onSubmit={submitUserLogin}
          >
            <div className="control has-icons-left">
              <input
                className="input"
                type="text"
                name="github-username"
                aria-label="github-username"
                placeholder="What's your GitHub username?"
                defaultValue="Bobby"
                onChange={e => setUserLogin(e.target.value)}
              />
            </div>
            <div className="control">
              <button data-testid="button" className="button">
                Submit
              </button>
            </div>
          </form>
          ...
    );
  };

  return user ? <CV data-testid="CV" user={user} /> : gitHubUsernameForm();
}

export default Landing;

В основном, нажав «Отправить» в Landing. js вызывает submitUserLogin(), который запускает getGitHubProfile() в запросе. js для использования client из apolloClient. js, чтобы запросить GitHub для прочее.

Если звонок сделан, <CV data-testid="CV" user={user} /> должен появиться. Сейчас его нет, но я также попытался вставить user ? <p data-testid="CV">Testing only</p> : null в макет на случай, если data-testid не работает с компонентами (я пока не знаком с тестированием).

Это хорошо работает на сам сайт, когда я запускаю npm start.

Однако я не могу понять, как проверить, выполнен ли вызов API. После прочтения документации по Apollo и response-testing-library и множества попыток я думаю, что сейчас это наиболее близкое к работоспособному решению:

import Landing from "../Landing";
import { MockedProvider } from "@apollo/react-testing";
import { userQuery } from "../query";

const mocks = [
  {
    request: {
      query: userQuery,
      variables: {
        login: "Bobby"
      }
    },
    result: {
      data: {
        user: { location: "South Woobeewoo" }
      }
    }
  }
];

it("Calls API", async () => {
  const { getByLabelText, getByText, getByTestId } = render(
    <MockedProvider mocks={mocks} addTypename={false}>
      <Landing />
    </MockedProvider>
  );
  const input = getByLabelText("github-username");
  fireEvent.change(input, { target: { value: "Bobby" } });
  console.log(input.value); // Shows input is successful.

  fireEvent.click(getByText("Submit"));

  const response = await waitForElement(() => getByTestId("CV")); // Always fails here.
  expect(response).toBeTruthy();
});

Тест всегда завершается с ошибкой «Unable to найти элемент по: [data-testid = "CV"] ".

Я знаю, fireEvent.click() работает, потому что я также пытался настроить это событие click на состояние pressed (теперь удалено) для запуска внешний вид тестовых элементов, помеченных data-testid="CV".

Я попробовал шаблон тестирования в официальных документах Apollo здесь , запустив отправку в самой форме, как здесь , это один тоже. Также прочитайте документацию по тестированию здесь о событиях стрельбы.

Я думаю, что я просто как-то не правильно делаю насмешку. Что я делаю не так?

...