API разработки для приемочных тестов node JS

Я создал приемочные тесты для своей библиотеки. Когда библиотека будет опубликована, она будет использовать внешнюю службу API, которая еще недоступна. Поэтому я создал фиктивный json API-сервер, который возвращает требуемый JSON для тестирования. Что мне нужно сделать, чтобы пройти тесты, так это вручную изменить URL-адрес API в файле, в котором сделан запрос.

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

return fetch('http://liveURL.com/api')
  .then(response => {
    if (response.status === 200) {
      return response.json()
        .then(myResponse => {
          var theResponse = myResponse.id;

          return theResponse;
        });
    } else {
      return response.json().then(error => {
        throw new Error(error.error);
      });
    }
  });

Что я хочу сделать при запуске только приемочных тестов, так это изменить URL-адрес, 'http://liveURL.com/api', я получаю запрос от к 'http://localhost:3000/api'.

Мок-сервер, который я использую, можно найти здесь: https://github.com/typicode/json-server

РЕДАКТИРОВАТЬ: В ответ на вопросы Бена, вот мой package.json, где я пытаюсь установить NODE_ENV

{
  "name": "my-lib",
  "version": "0.1.0",
  "description": "",
  "main": "lib/myLib",
  "private": true,
  "scripts": {
    "lint": "gulp lint",
    "pretest": "npm run lint",
    "test": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter spec \"test/unit/**/*.spec.js\"",
    "acceptance-test": "NODE_ENV=test cucumberjs",
    "build": "gulp build"
  },
  "author": "Me",
  "license": "ISC",
  "devDependencies": {
    "babel-preset-es2015": "^6.16.0",
    "babel-register": "^6.16.3",
    "babelify": "^7.3.0",
    "browserify": "^13.1.0",
    "chai": "^3.5.0",
    "chai-as-promised": "^5.3.0",
    "config-browserify": "^1.0.5",
    "cors": "^2.8.1",
    "cucumber": "^0.10.3",
    "eslint": "^3.0.1",
    "eslint-teamcity": "^1.1.0",
    "express": "^4.14.0",
    "gulp": "^3.9.1",
    "gulp-eslint": "^3.0.1",
    "gulp-sourcemaps": "^1.6.0",
    "gulp-uglify": "^2.0.0",
    "isomorphic-fetch": "^2.2.1",
    "istanbul": "v1.1.0-alpha.1",
    "jsdom": "^9.8.3",
    "json-server": "^0.9.1",
    "mocha": "^2.5.3",
    "mocha-jsdom": "^1.1.0",
    "mocha-teamcity-reporter": ">=0.0.1",
    "nock": "^9.0.0",
    "node-localstorage": "^1.3.0",
    "portscanner": "^2.1.0",
    "proxyquire": "^1.7.10",
    "selenium-server": "^2.53.0",
    "selenium-webdriver": "^2.53.2",
    "semver": "^5.3.0",
    "serve-static": "^1.11.1",
    "sinon": "^1.17.4",
    "sinon-chai": "^2.8.0",
    "vinyl-buffer": "^1.0.0",
    "vinyl-source-stream": "^1.1.0",
    "watchify": "^3.7.0"
  },
  "dependencies": {
    "config": "^1.21.0"
  }
}

Я создал два своих сервера в world.js. Один сервер для запуска библиотеки, на котором находится порт 23661, и один сервер, на котором находится поддельный API, на котором находится порт 3000. Это можно увидеть ниже.

'use strict';

const SeleniumServer = require('selenium-webdriver/remote').SeleniumServer;
 const webdriver = require('selenium-webdriver');
const server = new SeleniumServer(require('selenium-server').path, {port: 4444});
const serveStatic = require('serve-static');
const express = require('express');
const chaiAsPromised = require('chai-as-promised');
const chai = require('chai');
const jsonServer = require('json-server');
const cors = require('cors');

chai.should();
chai.use(chaiAsPromised);

const testServer = jsonServer.create();
const router = jsonServer.router('db.json');

testServer.use(cors());
testServer.options('*', cors());
testServer.use(router);
testServer.listen(3000);

const app = express();
const httpServerPort = 23661;
app.use(cors());
app.options('*', cors());
app.use(serveStatic('dist'));
app.use(serveStatic(__dirname + '/../page'));
app.use(serveStatic('node_modules/sinon/pkg'));
app.listen(httpServerPort);

server.start();

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

Файл, в который я пытаюсь позвонить

process.env.NODE_ENV

находится в моей свернутой библиотеке под названием myLib.min.js.

Вот часть неминифицированного файла

'use strict';

const fetch = require('isomorphic-fetch');

module.exports = id => {
  var apiUrl = 'http://liveurl.com/api/' + id;

  if (process.env.NODE_ENV === 'development') {
    apiUrl = 'http://localhost:3000/api';
  }

  console.log(process.env.NODE_ENV);

    return fetch(apiUrl)
      .then(response => {
        if (response.status === 200) {
          return response.json()
            .then(myResponse => {
              var theResponse = myResponse.id;

              return theResponse;
            });
        } else {
          return response.json().then(error => {
            throw new Error(error.error);
          });
        }
      });
};

person Christopher Jenks    schedule 23.11.2016    source источник


Ответы (1)


Обычно это решается с помощью переменных среды.

Что-то типа:

var apiUrl = 'http://localhost:3000/api'
if (process.env.NODE_ENV === 'production') {
  apiUrl = 'http://liveurl.com/api';
}

return fetch(apiUrl)
  .then(response => {
  //... and so on

Затем вы должны запустить свое приложение (или запустить тесты) таким образом, заполнив соответствующее имя среды для NODE_ENV. Общие значения: производство|тестирование|разработка:

NODE_ENV=production node ./path/to/app.js
person Ben    schedule 23.11.2016
comment
Спасибо, поэтому я запускаю свои тестовые серверы в world.js с помощью команды «npm run acceptation-test», так будет ли это в world.js, где я устанавливаю NODE_ENV? - person Christopher Jenks; 24.11.2016
comment
Нет, вы бы побежали NODE_ENV=test npm run acceptance-test - person Ben; 24.11.2016
comment
Итак, у меня есть "acceptance-test": "NODE_ENV=development cucumbers" в моем package.json. Теперь, когда я запускаю npm run acceptance-test, мои тесты будут запускаться с NODE_ENV, установленным на «разработку»? Однако, когда я добавляю console.log(process.env.NODE_ENV) в свой код перед предоставленным вами оператором if, он говорит, что это undefined. - person Christopher Jenks; 24.11.2016
comment
Хм... Странно. Можете ли вы поделиться сутью вашего package.json и вашего тестового файла? - person Ben; 24.11.2016
comment
Просто предупреждаю, что это противоречит общепринятой методологии, описанной в приложении Twelve Factor. Менее вонючим решением было бы установить API_URL env var и просто использовать все, что там есть, а не включать NODE_ENV. :) - person J.M. Janzen; 06.01.2021