Почему мой макет моего api возвращает ошибку 404?

#reactjs #jestjs #axios #enzyme #axios-mock-adapter

#reactjs #jestjs #axios #фермент #axios-макет-адаптер

Вопрос:

Я использую axios-mock-adapter для создания макета моего API, он работает корректно, но в одном макете он возвращает ошибку 404, и я не могу найти, почему.

Здесь есть песочница с тестом, вы можете увидеть, когда мы запустим тест, вторая проверка не удалась, потому что axios POST вызов не был макетом. Я попытался удалить часть заголовка, но в песочнице произошел сбой, когда я запустил test.


Макет API (тестовая часть):

 import axios from "axios";
import MockAdapter from 'axios-mock-adapter';
import Utils from "../Utils/Utils";

// Global variable for post request with axios
global.users_post = axios.create({
  baseURL: "http://localhost:5000/api/",
  headers: {'Content-Type': 'application/json'}
});

/* Mockup API */
var userMock = new MockAdapter(users_post);

const user_resp_full = {
  data: {
    first_name: "Test",
    last_name: "Test",
    email: "test@gmail.com",
    address: "Test",
    zipcode: 1010,
    city: "Test",
    admin: false
  }
}

const testAPI = () => {
    userMock
      .onPost("users", user_resp_full, Utils.getAuth())
      .reply(200, {data: {status: "success"}});
}

test("something", async () => {
  let tree = shallow(<UserManage type="create" uuid="" />);
  testAPI();
  await flushPromises();
  // Some test

  tree.find("#confirm-create").simulate("click");
  await flushPromises();
  // Error 404, mock isn't trigger
})
  

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


Вызов Axios в классе:

 function (fields) {
    users_post.post("users", fields, Utils.getAuth())
    .then(resp => {
      let data = resp.data;
      // Do something
    })
    .catch(resp => {
      let data = resp.response.data;
      // Display error
    });
}
  

На данный момент в моем тесте Jest он возвращает ошибку 404, поэтому он не имитировал мой endpoint API (другие работы).
Utils.getAuth() Функция возвращает заголовок с токеном аутентификации.


Отправка данных

Это касается содержимого отправляемых данных (первое — перед тестовым вызовом с макетом, второе — в тестируемой функции, а журнал данных — это данные, отправляемые в api):

 console.log src/tests/UserManage.test.js:222
  POST USER 2
{"first_name":"Test","last_name":"Test","email":"test@gmail.com","address":"Test","zipcode":1010,"city":"Test","admin":false}
console.log src/Components/Users/UserManage.js:152
  POST USER
console.log src/Components/Users/UserManage.js:153
{"first_name":"Test","last_name":"Test","email":"test@gmail.com","address":"Test","zipcode":1010,"city":"Test","admin":false}
  


Обновить

Эта ошибка возникает только тогда, когда я использую POST запрос с подобным заголовком:

 axios.post("http://localhost/api/user/update", {name: "Test"}, {headers: {"Authorization": "Bearer token")}});
  

Я вижу на тестовой странице axios-mock-adapter github, что в конечном итоге мы должны поставить headers тест без метки перед:
{headers: {Autorization: "Bearer token"}} стать {Autorization: "Bearer token"}
Но, к сожалению, это работает не лучше, чем у меня.


Решение

С ответом Мэтта Карлотты и его codesandbox я модифицирую свой с помощью 2 примеров исправленной проблемы:

  • Проверка POST макета запроса с использованием axios*
  • Проверка POST макета запроса с использованием экземпляра axios*

* С axios-mock-adapter

Комментарии:

1. Возможно, это совершенно не связано, но в вашей функции testApi ничего не возвращается. На самом деле я не вижу смысла в функции testApi, что, если вы поместите свой userMock.onPost() … непосредственно в свой тест («что-то»)?

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

3. вы пробовали добавлять начальную косую черту к вашему onPost вызову ‘/users’? во всех примерах показаны ведущие косые черты, github.com/ctimmerm/axios-mock-adapter

4. @N3SS4H Да, но я использую конфигурацию axios, у которой в baseUrl есть ..базовый URL, например http://localhost:5000/ , и я тестирую его, но он не работает.

Ответ №1:

Отлично, второй раунд.

  • Ваша flushPromises функция не решается promises должным образом, когда для ответа на это promise требуется некоторое время. Обходной путь заключается в том, чтобы return promise вставить await перед ним в .test.js файл. Поскольку мы используем await на promise , await flushPromises() не требуется.
  • Кроме того, включение headers в onPost издевательскую функцию приведет к тому, что функция выдаст ошибку. Поскольку вы просто издеваетесь над этим запросом (а на самом деле не тестируете его интеграцию), вам не нужно их включать. Однако, поскольку вы все равно уже используете пользовательскую axios конфигурацию, вы можете просто включить headers в axiosConfig.js файл. Смотрите рабочий пример вашего codesandbox для получения дополнительной информации.

Как показано в Unit Testing codesandbox ниже, если вы попытаетесь использовать метод await flushPromises() on deleteUserDataOverTime , произойдет сбой. Сбой, потому что он не разрешил promise . Для устранения этого promise требуется некоторое время, и оно не обрабатывается должным образом.

Кроме того, из-за asynchronous характера тестов вы не должны включать unit и integration тесты в один и тот же тестовый файл. Поскольку тесты asynchronous , вызывающие mockAxios.reset() or mockAxios.restore() по тому же поддельному запросу или тому же поддельному экземпляру — для выполнения любых дополнительных реальных или поддельных вызовов API — могут и будут непреднамеренно влиять на все вызовы API (опять же, это асинхронные, а не синхронные тесты).

Рабочий пример модульного тестирования API: https://codesandbox.io/s/6z36z6pzyr (поддельный API — включает GET , PUT POST и DELETE )

Рабочий пример интеграционного тестирования API: https://codesandbox.io/s/7z93xnm206 (реальный API — включает только GET , но функциональность должна оставаться неизменной для PUT , POST и DELETE )

Рабочий пример вашего codesandbox: https://codesandbox.io/s/526pj28n1n

Комментарии:

1. Ваш ответ на самом деле не помогает мне в решении моей проблемы, вы описываете тест с GET запросом, но никто не сообщает о POST запросе с заголовком, который может быть ошибкой. Однако я создам тест, который можно воспроизвести.

2. Да, это имеет значение, потому что мой GET запрос (тот же, что и в вашем тесте) в моем тесте работает отлично, но это было не так с моим POST запросом, который все не удался. Итак, я ищу, почему POST запрос не удался, но я собираюсь создать тест в изолированной среде с этим.

3. Я добавил ссылку на изолированную среду.

4. Пожалуйста, прочитайте внимательно: тест реализации API (он же Unit Test ) будет имитировать request , side effect и result . Тест интеграции API (он же End to End Test ) фактически протестирует request , side effect и result от клиента к API. Я также обновил свой ответ выше, чтобы подчеркнуть различия.

5. Уверен, что я разобрался с вашей проблемой. Смотрите обновленный ответ выше.

Ответ №2:

Хорошо, это было сложно. Проблема в пакете axios-mock-adapter. Для этого требуется экземпляр axios, использующий .create() метод. Смотрите здесь: создание экземпляра

В вашем App.js, используйте:

 import axios from "axios";
const instance = axios.create();

instance.post("http://localhost/api/user/update", {name: "Test"}, {headers: {"Authorization": "Bearer token")}});
  

Однако в тестах ничего не нужно менять.

Я получил подсказку из тестов axios-mock-adapter.

Примером такого является: post test

Комментарии:

1. Как и на github axios-mock-adapter , я отправляю вам CodeSandbox , обновленный вашим решением, но это не работает. Кроме того, в моей проблеме уже используется экземпляр axios с пользовательской конфигурацией и тоже не работает.