JavaScript

4 способа подделки API во фронтенд-разработке

Spread the love

Перевод: Valentino Gagliardi4 ways to fake an API in frontend development

Для кого это руководство и что вам нужно знать

Это руководство предполагает базовое понимание теории тестирования и опыт работы с тестовыми фреймворками.

Примеры в статье написаны на чистом JavaScript.

Чтобы поэкспериментировать с примерами, у вас должна быть рабочая установка Node.js в вашей системе.

Чтобы сразу перейти к тренировкам, прыгайте сюда, иначе сначала рассмотрим немного теории!

Терминология: stubbing, mocking и поддельное API

Потребность в поддельных API

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

Представьте фрагмент кода для получения данных из RESTFUL API и, в частности, его ответ — это всегда дополнительная зависимость для нашего кода.

Получение и отображение данных — один из наиболее распространенных вариантов использования фронтендовского кода. Обычно это делается путем обращения к внешнему RESTFUL API, который содержит для нас некоторый JSON. При этом нужно учитывать что не правильно вызывать настоящее продуктовое API в тестовой среде или в процессе разработке. Есть ряд причин не делать этого.

Во-первых, тесты не должны зависеть от внешних сервисов. Тест с использованием реального API может завершиться неудачно, если:

  • у реального API периодически возникают проблемы с сетью
  • у реального API есть ограничения по скорости
  • само API может работать медленно из-за больших объемов данных
  • и т.п.

С другой стороны, вы сами не захотите использовать продуктовое API в разработке потому, что:

  • продуктовое API может быть платной услугой
  • вы можете находиться за брандмауэром, которое ограничивает исходящие соединения
  • так же API ограничивать время отработки тестов

Кроме того, чаще всего фронтенд-разработчики нуждаются и хотят разрабатывать независимо от бекенд составляющей, например потому что RESTFUL API может быть не готово на 100%.

Именно здесь в игру вступают mocking и stubbing.

Что такое mocking? Что такое stubbing?

В разработке программного обеспечения mocking (фиктивный, ложный) и stubbing (заглушка) — два термина, тесно связанные с тестированием.

Важно отметить, что понятие «фейки» в тестировании и в разработке никоим образом не ново. Есть еще одно определение этих «фейков»: тестовые двойники.

В контексте типичного внешнего интерфейса mocking и stubbing помогают «подделать» реальное API, заменив его сфабрикованным сервисом или «хирургической» подменой одной функции.

Это особенно полезно при работе с независимыми интерфейсными архитектурами, которые чаще всего взаимодействуют с удаленными API, и не всегда находящимися под нашим прямым контролем.

В чем разница между mocking и stubbing?

  • Mocking означает замену одной или нескольких функций при тестировании поддельной копией.
  • Stubbing означает замену некоторой внешней службы или сетевого ответа поддельной версией.

Итак, mocking или stubbing?

Как видите, разница между mocking и stubbing не так очевидна.

Рассмотрим этот момент подробнее:

Mocking направлен на замену так называемых исходящих зависимостей наших тестов: обычно это сетевые вызовы. Например, мы можем имитировать Fetch или XMLHttpRequest и заменить фактическую функцию нашей собственной версией.

Stubbing — это метод замены сетевых ответов.

Большинство инструментов mocking/stubbing работают путем перехвата и замены функций Fetch или XMLHttpRequest, таким образом чтобы предоставить поддельный ответ. В более строгом смысле они всегда имитируют исходящие сетевые функции.

Другая категория инструментов, такая как json-server, — это полноценный stubs (заглушка), потому что они не затрагивают тестируемый код.

У обоих методов есть свои варианты использования. В этой статье я рассмотрю наиболее распространенные подходы к mocking и stubbing в контексте веб-приложения.

Настройка проекта

Для начала клонируйте этот репозитарий минимальная среда разработки:

git clone https://github.com/valentinogagliardi/stubbing-mocking.git

cd stubbing-mocking

Внутри установите зависимости:

npm i

Откройте проект в своем любимом редакторе.

Mirage JS

Начнем этот тур с первой библиотеки группы: Mirage JS. Основанный на другой библиотеке, Pretender, он предлагает интересный подход к mocking API.

Установка Mirage js

Чтобы установить библиотеку в свой проект, выполните:

npm i miragejs --save-dev

Сценарий

Мы хотим перехватить и имитировать ответ API в процессе разработки или тестирования.

API mocking с Mirage Js

Предположим, у нас есть часть интерфейса, где пользователь щелкает и запускает вызов Fetch. Чтобы продолжить, создайте новый HTML-файл в src/index.html со следующим содержимым:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Mocking and stubbing in frontend development</title>
</head>
<body>
<div>
    <button id="fetch-btn">FETCH</button>
</div>
</body>
</html>

В другой файл, src/index.js пропишите следующую логику:

/*
Получить данные при нажатии кнопки
 */const button = document.getElementById("fetch-btn");

button.addEventListener("click", function() {
  fetch("/api/users/")
    .then(response => {
      if (!response.ok) throw Error(response.statusText);
      return response.json();
    })
    .then(json => buildList(json));
});

/*
Создаем список пользователей
 */function buildList(data) {
  console.log(data);
}

Примечание: файл должен быть в точности в src/index.js, потому что он будет загружаться webpack.

Чтобы перехватить вызов /api/users/ с помощью Mirage JS, мы можем использовать объект Server, настроенный с поддельной конечной точкой:

import { Server } from "miragejs";

new Server({
  routes() {
    this.namespace = "api";

    this.get("/users/", () => {
      return [
        { name: "Angy", surname: "T." },
        { name: "Chris", surname: "B." },
        { name: "Juliana", surname: "Crain" }
      ];
    });
  }
});

Этот код может находиться в том же файле src/index.js для простоты или в другом файле, импортированном в проект.

Вот полный код src/index.js:

import { Server } from "miragejs";

new Server({
  routes() {
    this.namespace = "api";

    this.get("/users/", () => {
      return [
        { name: "Angy", surname: "T." },
        { name: "Chris", surname: "B." },
        { name: "Juliana", surname: "Crain" }
      ];
    });
  }
});

const button = document.getElementById("fetch-btn");

button.addEventListener("click", function() {
  fetch("/api/users/")
    .then(response => {
      if (!response.ok) throw Error(response.statusText);
      return response.json();
    })
    .then(json => buildList(json));
});

function buildList(data) {
  console.log(data);
}

Теперь запустите проект с помощью команды:

npm start

Откройте консоль браузера и нажмите кнопку. Вы должны увидеть в консоли следующий вывод:

Как видите, Mirage JS перехватывает запрос и выдает ложный ответ. Конфигурация довольно проста. Мы можем определить пространство имен для API:

this.namespace = "api";

Мы так же можем определять маршруты (он принимает все методы HTTP):

    this.get("/users/", () => {
        // return a response
    });

Таким образом, при переходе к /api/users/ Mirage JS выполняет подделку ответа. И это лишь краткий обзор того, что умеет Mirage JS.

Mirage JS даже имеет свое ORM, с поддержкой моделей и отношений между ними. Я рекомендую вам почитать документацию для более сложных примеров.

Поскольку Mirage JS потенциально может перехватывать все сетевые запросы, вы должны быть осторожны, импортируя его в процессе разработки.

В проектах на основе webpack (Reat, Vue) вы можете положиться на process.env.NODE_ENV для динамического импорта и организации загрузки библиотеки только в процессе разработки и тестирования:

const loadMirage = () => import("miragejs");

export function loadMirageInDev() {
  if (process.env.NODE_ENV === "development") {
    loadMirage().then(({ Server }) => {
      return new Server({
        routes() {
          this.namespace = baseURL;

          this.get("/users/", () => {
            return [/* your stuff here */];
          });

          this.get("/articles/", () => {
            return [/* your stuff here */];
          });
        },
      });
    });
  }
}

Эта логика должна находиться в отдельном файле, который вы импортируете в основную точку входа.

Просто имейте в виду, что если вы вызываете API при монтировании компонента, например created во Vue, или componentDidMount/useEffect в React, вам необходимо загрузать Mirage JS до визуализации оболочки приложения.

Другой вариант — импортировать Mirage JS только на стадии тестирования.

Это mocking или stubbing? Поскольку Mirage JS заменяет Fetch и XMLHttpRequest для предоставления ложного ответа, то мы можем сказать, что это mocking. Но для нас это прозрачно, потому что в нашем коде нам не нужно напрямую изменять Fetch или XMLHttpRequest.

MSW — это еще один инструмент, который попадает в ту же категорию, что и Mirage JS, но работает в Service Worker. Посмотрите это для сравнения.

Jest

Jest — это средство запуска тестов JavaScript, то есть библиотека JavaScript для создания, выполнения и структурирования тестов.

Jest — один из самых популярных средств запуска тестов в наши дни и выбор по умолчанию для многих проектов.

Сценарий

Мы хотим перехватить и имитировать ответ API при модульном тестировании.

Установка и конфигурирование Jest

Чтобы установить библиотеку в свой проект, выполните команду:

npm i jest --save-dev

Давайте также настроим сценарий NPM для запуска наших тестов из командной строки.

Откройте package.json и настройте сценарий под названием «test» для запуска Jest:

  "scripts": {
    "test": "jest"
  },

Поскольку мы запускаем Jest из командной строки через Node.js, который не включает Fetch API, нам нужно установить полифилл для Node:

npm i whatwg-fetch --save-dev

По умолчанию Jest ожидает найти тестовые файлы в папке с именем __tests__ в папке вашего проекта.

Создайте новую папку с этим именем и внутри нее создайте файл APITest.spec.js. Через мгновение мы запустим первый тест.

Mocking Fetch с Jest

В этом тесте мы собираемся протестировать функцию, которая вызывает /api/users/ удаленного API. Мы хотим проверить, что функция возвращает массив пользователей из API:

const { getUsers } = require("../src/common/usersAPI");

beforeAll(() => {
  require("whatwg-fetch");
});

describe("Users API", () => {
  test("it returns an array of users", async () => {
    const expected = [
      { name: "Jonas", surname: "T." },
      { name: "Chris", surname: "B." },
      { name: "Juliana", surname: "Crain" },
      { name: "Caty", surname: "B." }
    ];

    const json = await getUsers();
    expect(json).toMatchObject(expected);
  });
});

Здесь мы импортируем getUsers из внешнего модуля (мы собираемся создать его через минуту). Затем мы проверяем, возвращает ли getUsers ожидаемый ответ.

С помощью beforeAll мы загружаем полифилл Fetch, whatwg-fetch, чтобы сделать наш тест максимально реалистичным. (Это не всегда необходимо, особенно с приложениями вроде create-react-app и т.п.).

Перед запуском теста создайте новый файл в src/common/usersAPI.js со следующим кодом:

const ENDPOINT = "https://api.valentinog.com/api/users/";

function getUsers() {
  return fetch(ENDPOINT)
    .then(response => {
      if (!response.ok) throw Error(response.statusText);
      return response.json();
    })
    .then(json => json);
}

module.exports = { getUsers };

Теперь запустите тест с помощью команды:

npm test

Вы должны увидеть следующие ошибки:

TypeError: Network request failed
// and
Error: Cross origin http://localhost forbidden

Я ожидаю этого, потому что URL, по которому мы обращаемся, еще не существует на сервере, поэтому бэкэнд не может установить заголовок CORS. Подумайте о реалистичном сценарии, в котором вам нужно разработать пользовательский интерфейс, но бэкэнд еще не готов на 100%.

Эта ошибка — хорошая возможность имитировать (mock) Fetch, чтобы мы могли заменить window.fetch поддельной версией.

Во-первых, в тесте мы используем метод Jest spyOn для перехвата метода:

    jest.spyOn(window, "fetch").mockImplementation(() => {
      // TODO
    });

Затем мы предоставим поддельную версию ответа Fetch:

    jest.spyOn(window, "fetch").mockImplementation(() => {
      const fetchResponse = {
        ok: true,
        json: () => Promise.resolve(expected)
      };
      return Promise.resolve(fetchResponse);
    });

Вот полный тест:

const { getUsers } = require("../src/common/usersAPI");

beforeAll(() => {
  require("whatwg-fetch");
});

describe("Users API", () => {
  test("it returns an array of users", async () => {
    const expected = [
      { name: "Jonas", surname: "T." },
      { name: "Chris", surname: "B." },
      { name: "Juliana", surname: "Crain" },
      { name: "Caty", surname: "B." }
    ];

    jest.spyOn(window, "fetch").mockImplementation(() => {
      const fetchResponse = {
        ok: true,
        json: () => Promise.resolve(expected)
      };
      return Promise.resolve(fetchResponse);
    });

    const json = await getUsers();

    expect(json).toMatchObject(expected);
  });
});

В конце каждого теста, если необходимо, восстановите реальную версию Fetch с помощью mockRestore():

const { getUsers } = require("../src/common/usersAPI");

beforeAll(() => {
  require("whatwg-fetch");
});

describe("Users API", () => {
  test("it returns an array of users", async () => {
    // пропущено ....
     
    // возвращаем исходное состояние
    window.fetch.mockRestore();    

  });
});

Таким образом, вы не будете мешать другим тестам.

Теперь запустите тест, и теперь он должен пройти успешно:

npm test

Spying в Jest

Mocking — это не только замена функций подделками, но и слежка за вызовами функций.

Ранее мы видели, что mocking — это также когда вы оцениваете фиктивную функцию, чтобы увидеть:

  • была ли оная вызвана другим фрагментом кода
  • сколько раз был вызвана
  • какие были использованы параметры

В Jest мы можем сделать подобное утверждение для mocked функции следующим образом:

beforeAll(() => {
  require("whatwg-fetch");
});

describe("Users API", () => {
  test("it returns an array of users", async () => {

    // пропущено...

    expect(window.fetch).toHaveBeenCalledWith(
      "https://api.valentinog.com/api/users/"
    );

    expect(window.fetch).toHaveBeenCalledTimes(1);

    expect(json).toMatchObject(expected);

    window.fetch.mockRestore();
  });
});

Вот что мы проверили:

  • функция была вызвана с соответствующим параметром
  • функция была вызвана ровно один раз

Это mocking или stubbing? Это правильный mocking, потому что мы намеренно заменяем Fetch нашей собственной версией, чтобы изменить ответ и подтвердить его вызов.

Cypress

Cypress — это инструмент для выполнения функциональных (также называемых сквозными) тестов. В отличие от таких средств запуска тестов, как Jest, которые работают на уровне модулей, Cypress запускает настоящий браузер для проведения тестов.

(Недавно Cypress также получил возможность запускать модульные тесты, но это уже другая история).

К сожалению, на сегодняшний день Cypress все еще не может перехватить Fetch, но работа над добавлением его поддержки продолжается. Начиная с версии 4.9.0 Cypress имеет экспериментальную поддержку Fetch stubbing. Чтобы включить его, настройте experimentalFetchPolyfill в cypress.json:

{
  "experimentalFetchPolyfill": true
}

В этом разделе мы увидим, как заменить (stub) ответ от XMLHttpRequest.

Сценарий

Мы хотим перехватить и заменить ответ API при функциональном тестировании.

Установка и настройка Cypress

Чтобы установить Cypress в свой проект, выполните команду:

npm i cypress --save-dev

После установки запустите тест первый раз с помощью команды:

node_modules/.bin/cypress open

В вашем проекте появится куча новых папок. Вы можете безопасно удалить папку с примером example.

Давайте также настроим сценарий NPM для запуска наших тестов из командной строки.

Откройте package.json и настройте скрипт с именем «e2e» для запуска Cypress:

  "scripts": {
    "e2e": "cypress open"
  },

По умолчанию Cypress ожидает найти тестовые файлы в папке cypress/integration вашего проекта.

Создайте тест в файле cypress/integration/APITest.spec.js. Через мгновение мы запустим свой первый тест Cypress.

Замена сетевого ответа с помощью Cypress

Структура теста Cypress напоминает то, что мы видели с Jest:

describe("Users API", () => {
  it("should return an array of users", () => {
    //
  });
});

У нас есть функции describe и it и они имеет то же значение, что и тестовых блоках Jest.

В описание действия в функциональном тесте вместо того, чтобы сказать «должен возвращать массив пользователей — should return an array of users», мы можем сказать «должен увидеть список пользователей — should see a list of users», потому что нам нужно выдать себя за реального пользователя, использующего браузер. Поэтому наш тест будет выглядеть так:

describe("Users API", () => {
  it("should see a list of users", () => {
    //
  });
});

Теперь представьте, что мы хотим подделать ответ для той же конечной точки «/api/users/«.

В Cypress мы используем функцию cy.server для отслеживания сетевых запросов, и cy.route для настройки поддельной конечной точки API:

describe("Users API", () => {
  it("should see a list of users", () => {
    cy.visit("http://localhost:8080/");

    cy.server();
    cy.route({
      url: "/api/users/",
      method: "GET",
      response: [
        {
          name: "Juliana",
          surname: "Crain"
        },
        { name: "Molly", surname: "F." }
      ]
    });

    cy.contains("FETCH").click();
  });
});

Чтобы попробовать этот тест, убедитесь, что src/index.html все еще на месте со следующим содержимым:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Mocking and stubbing in frontend development</title>
</head>
<body>
<div>
    <button id="fetch-btn">FETCH</button>
</div>
</body>
</html>

В src/index.js нам нужно изменить логику, чтобы использовать XMLHttpRequest вместо Fetch:

const button = document.getElementById("fetch-btn");

button.addEventListener("click", function() {
  // AJAX запрос с XMLHttpRequest
  const request = new XMLHttpRequest();
  request.open("GET", "/api/users/");
  request.onload = function() {
    const jsonResponse = JSON.parse(this.response);
    buildList(jsonResponse);
  };
  request.send();
});

function buildList(data) {
  console.log(data);
}

Теперь запустите тест в терминале:

npm start

В другом терминале запустите Cypress:

npm run e2e

Вы увидите всплывающее окно, выберите тест, который мы написали минуту назад, и убедитесь, что тест прошел:

Вы можете увидеть XHR STUB как подтверждение stubbing (заглушки).

В этом тесте мы просто заменили ответ, но вы можете легко создать список с помощью JavaScript и добавить тест для проверки списка HTML в DOM.

Это mocking или stubbing? В отличие от Mirage JS или spyOn от Jest, Cypress обертывает и наблюдает за XMLHttpRequest, чтобы при необходимости предоставить ложный ответ, он не имитирует каждый вызов. Но когда мы используем cy.route, Cypress должен заменить XMLHttpRequest на поддельную версию. Поэтому, несмотря на то, что в документации они определяют этот подход как stubbing, технически это все еще mock.

В будущем Cypress будет использовать прозрачный прокси-слой для stubbing сети.

json-server

Последний инструмент этого тура — json-server, это еще один пакет NPM для создания stubbing API. json-server — это HTTP-сервер, который может прослушивать локальную (или удаленную) сеть.

Сценарий

Мы хотим перехватить и заменить ответ от API при разработке и тестировании.

Установка и запуск json-server

Чтобы установить json-сервер в свой проект используйте следующую команду:

npm i json-server --save-dev

Затем создайте новый файл с именем db.json в папке проекта. Этот файл будет содержать поддельную базу данных для нашего сервера. В нем может быть что-то в этом роде:

{
  "users": [
    {
      "name": "Jonas",
      "surname": "T."
    },
    {
      "name": "Chris",
      "surname": "B."
    },
    {
      "name": "Juliana",
      "surname": "Crain"
    },
    {
      "name": "Caty",
      "surname": "B."
    }
  ]
}

Теперь откройте package.json и настройте скрипт с именем «stubapi» для запуска json-сервера:

  "scripts": {
    "stubapi": "json-server db.json",
    "test": "jest",
    "e2e": "cypress open"
  },

Для запуска сервера выполните команду:

npm run stubapi

В консоли вы должны увидеть следующий вывод:

  Resources
  http://localhost:3000/users

  Home
  http://localhost:3000

Это означает, что теперь вы можете получить доступ к http://localhost:3000/users, чтобы получить список поддельных пользователей.

Как видите, эта вся эта структура URLов — это первая проблема с json-server. Нелегко получить что-то вроде http://localhost:3000/api/users, не засорив конфигурацию дополнительным кодом.

json-server требует собственный список маршрутов и ответов, и в большинстве случаев это усложняет проект.

Теперь, когда установлен поддельный сервер, мы можем тестировать как модульные, так и функциональные тесты.

Модульный тест с Jest и json-сервером

Чтобы протестировать заглушку с помощью Jest, откройте __tests__/APITest.spec.js, очистите все и внесите следующий код:

const { getUsers } = require("../src/common/usersAPI");

beforeAll(() => {
  require("whatwg-fetch");
});

describe("Users API", () => {
  test("it returns an array of users", async () => {
    const expected = [
      { name: "Jonas", surname: "T." },
      { name: "Chris", surname: "B." },
      { name: "Juliana", surname: "Crain" },
      { name: "Caty", surname: "B." }
    ];

    const json = await getUsers("http://localhost:3000/users");

    expect(json).toMatchObject(expected);
  });
});

В этом тесте нам больше не нужно имитировать (mock), мы просто вызываем API-заглушку.

Теперь откройте src/common/usersAPI.js и настройте функцию, чтобы она принимала следующий параметр:

function getUsers(endpoint) {
  return fetch(endpoint)
    .then(response => {
      if (!response.ok) throw Error(response.statusText);
      return response.json();
    })
    .then(json => json);
}

module.exports = { getUsers };

Теперь запустите в терминале:

npm run stubapi

В другом терминале запустите модульные тесты:

npm test

Тест должен пройти:

 PASS  __tests__/APITest.spec.js
  Users API
    ✓ it returns an array of users (3 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.962 s, estimated 1 s
Ran all test suites.

Теперь посмотрим на функциональный тест.

Функциональный тест с Cypress и json-server

Этот тест тоже простой. Откройте integration/APITest.spec.js, очистите все и внесите следующий код:

describe("Users API", () => {
  it("should see a list of users", () => {
    cy.visit("http://localhost:8080/");

    cy.contains("FETCH").click();

    cy.contains(/Jonas|Chris|Juliana/);
  });
});

В src/index.js не забудьте вызвать API-заглушку:

const button = document.getElementById("fetch-btn");

button.addEventListener("click", function() {
  // AJAX request with XMLHttpRequest
  const request = new XMLHttpRequest();
  request.open("GET", "http://localhost:3000/users/");
  request.onload = function() {
    const jsonResponse = JSON.parse(this.response);
    buildList(jsonResponse);
  };
  request.send();
});


function buildList(data) {
  const ul = document.createElement("ul");
  for (const user of data) {
    const li = document.createElement("li");
    li.innerText = user.name;
    ul.appendChild(li);
  }
  document.body.appendChild(ul);
}

Теперь, когда json-сервер все еще запущен, запустите приложение в терминале:

npm start

В другом терминале запустите Cypress:

npm run e2e

Вы увидите всплывающее окно, выберите тест, который мы написали минуту назад, и убедитесь, что тест прошел:

Это mocking или stubbing? json-server — типичный пример stubbing, потому что мы предоставляем фальшивую внешнюю службу нашим тестам, не затрагивая ничего в нашем коде (кроме небольшой корректировки URL-адреса в нашем примере).

Как настроить URL-адрес API в React и Vue

Неправильно жестко кодировать URL-адрес API в вызовах Fetch или XMLHttpRequest, особенно при использовании такого инструмента, как json-server.

Обычной практикой является использование другого URL-адреса в производственной среде и среде разработки (или тестировании).

В React

Создайте файл с именем .env.development в папке вашего проекта и настройте переменную среды с префиксом REACT_APP_:

REACT_APP_BASE_URL=http://localhost:3000

Затем в вашем коде получите доступ к переменной следующим образом:

    fetch(`${process.env.REACT_APP_BASE_URL}/users/`)
      .then(/* разместите ваш код сюда */)
      .then(/* разместите ваш код сюда */)
      .catch(/* здесь должен быть обработчик ошибок */);

Для производственной среды вместо этого создайте файл с именем .env.production в папке проекта и настройте переменную среды с префиксом REACT_APP_:

REACT_APP_BASE_URL=https://api.production.io

Ваш вызов Fetch остается прежним:

    fetch(`${process.env.REACT_APP_BASE_URL}/users/`)
      .then(/* разместите ваш код сюда */)
      .then(/* разместите ваш код сюда */)
      .catch(/* здесь должен быть обработчик ошибок */);

Подробнее см. в документации.

В Vue CLI

Создайте файл с именем .env.development в папке проекта и настройте переменную среды с префиксом VUE_APP_:

VUE_APP_BASE_URL=http://localhost:3000

Затем в вашем коде получите доступ к переменной следующим образом:

    fetch(`${process.env.VUE_APP_BASE_URL}/users/`)
      .then(/* разместите ваш код сюда */)
      .then(/* разместите ваш код сюда */)
      .catch(/* здесь должен быть обработчик ошибок */);

Для производственной среды вместо этого создайте файл с именем .env.production в папке проекта и настройте переменную среды с префиксом VUE_APP_:

VUE_APP_BASE_URL=https://api.production.io

Ваш вызов Fetch остается прежним:

    fetch(`${process.env.VUE_APP_BASE_URL}/users/`)
      .then(/* разместите ваш код сюда */)
      .then(/* разместите ваш код сюда */)
      .catch(/* здесь должен быть обработчик ошибок */);

Подробнее см. в документации.

Заключение

Здесь вы можете спросить, какой из всех этих инструментов для mocking и stubbing мне следует использовать?

Все зависит от ваших потребностей! Вот краткий обзор плюсов и минусов для принятия обоснованного решения.


json-server

Плюсы:

  • не нужно имитировать код, просто вызовите конечную точку API-заглушки
  • фейковый сервер тоже может находиться удаленно

Минусы:

  • фальшивый сервер должен быть всегда запущеным
  • если вы поставите поддельный сервер удаленно, у вас снова могут быть нестабильные запуски тесты (проблемы с сетью, таймауты)
  • вам придется писать больше кода на стороне сервера

Cypress stubbing

Плюсы:

  • не нужно имитировать код, просто вставьте используйте нужный вам ответ

Минусы:

  • на данный момент нет полноценной поддержки Fetch ответа на запрос

Jest mocking

Плюсы:

  • высокий контроль над ответами
  • может шпионить за вызовами и их параметрами

Минусы:

  • риски злоупотреблений имитации, используйте нужно использовать их разумно
  • подделка запросов иногда может потребовать слишком много дополнительного кода

Mirage JS

Плюсы:

  • много функций, ORM, отношения
  • нет необходимости дублировать серверный код
  • очень гибкий

МинусыПосмотрите, как он сравнивается с другими инструментами.

Есть что добавить? Напишите автору статьи!

Была ли вам полезна эта статья?
[4 / 5]

Spread the love
Editorial Team

Recent Posts

Vue 3.4 Новая механика v-model компонента

Краткий перевод: https://vuejs.org/guide/components/v-model.html Основное использование​ v-model используется для реализации двусторонней привязки в компоненте. Начиная с Vue…

12 месяцев ago

Анонс Vue 3.4

Сегодня мы рады объявить о выпуске Vue 3.4 «🏀 Slam Dunk»! Этот выпуск включает в…

12 месяцев ago

Как принудительно пере-отобразить (re-render) компонент Vue

Vue.js — это универсальный и адаптируемый фреймворк. Благодаря своей отличительной архитектуре и системе реактивности Vue…

2 года ago

Проблемы с установкой сертификата на nginix

Недавно, у меня истек сертификат и пришлось заказывать новый и затем устанавливать на хостинг с…

2 года ago

Введение в JavaScript Temporal API

Каким бы ни было ваше мнение о JavaScript, но всем известно, что работа с датами…

2 года ago

Когда и как выбирать между медиа запросами и контейнерными запросами

Все, кто следит за последними событиями в мире адаптивного дизайна, согласятся, что введение контейнерных запросов…

2 года ago