Макетируйте запрос axios для внешнего сервиса в тесте - PullRequest
0 голосов
/ 27 сентября 2018

Я пытаюсь смоделировать звонок на внешний сервис из NodeJS express.Я не могу заставить axios-mock-adapter перехватить фактический вызов axios (http://api.openweathermap.org)) и вернуть поддельный ответ. Когда подтверждение выполнено, оно терпит неудачу, потому что значения отличаются. Температура от вызова являетсяфактическая температура наружного воздуха, а не поддельная. Не знаю, полностью ли я выключен или близок ли я к решению, которое я не вижу. Вид нового для JavaScript и NodeJS.

ПожалуйстаStackoverflow, вы моя единственная помощь.

Это мой код:

Файл для проверки:

WeatherTools.prototype.getWeather = new Promise(function(resolve, reject) {

    axios.get(config.weather.openWeatherLocationURL, {
        params: {
            id: config.weather.openWeatherMapLocation,
            APPID: config.weather.openWeatherMapApiKey,
            units: config.weather.openWeatherUnit
        }
    }
    ).then(function(axiosResponse) {
        resolve(axiosResponse.data);
    }).catch(function(axiosError) {
        reject(axiosError);
    });
});

Тестовый файл:

const assert = require('assert');
const weatherTool = require('./weatertools');
const axios = require('axios');

let MockAdapter = require('axios-mock-adapter');
const TestData = require('./testData.js');

let mock = new MockAdapter(axios);

describe("Testing weather tools", () => {

    beforeEach(function() {
        mock
            .onGet(config.weather.openWeatherLocationURL, {
                params: {
                    id: config.weather.openWeatherMapLocation,
                    APPID: config.weather.openWeatherMapApiKey,
                    units: config.weather.openWeatherUnit
                }
            }).reply(200, TestData.location().mockedResponseData);
    });
    it('given a correct call to openWeather a valid response should be returned xxx', function(done) {

        weatherTool.WeatherTools.getWeather.then(function(actual) {
            assert.strictEqual(actual.temp.currentTemp, TestData.location().expected.temp.currentTemp);
            done();
        })
    });
});

Файл конфигурации:

config.weather.openWeatherMapApiKey = 'theSecretApiKeyOfMine';
config.weather.openWeatherMapLocation = '1234567';
config.weather.openWeatherUnit = 'metric';
config.weather.openWeatherLocationURL = 'http://api.openweathermap.org/data/2.5/weather';

1 Ответ

0 голосов
/ 27 сентября 2018

Проблема в проверенном коде.Ожидается, что getWeather член - это метод, который получает погоду, а это свойство обещания.Погода не получается, на самом деле погода.Поскольку это свойство prototype, оно охотно выполняет запрос определения класса, т. Е. Как только класс импортируется.Это также означает, что данные не могут быть обновлены в будущем, даже если в этом есть необходимость.

Поскольку запрос выполняется с энтузиазмом, на него не повлияет макет Axios.

getWeather также использует обещанный строительный антипаттерн;axios уже возвращает обещание, нет необходимости создавать еще одно с new Promise.

Оно должно быть:

WeatherTools.prototype.getWeather = () => {
    return axios.get(config.weather.openWeatherLocationURL, {
        params: {
            id: config.weather.openWeatherMapLocation,
            APPID: config.weather.openWeatherMapApiKey,
            units: config.weather.openWeatherUnit
        }
    }
    ).then(function(axiosResponse) {
        return axiosResponse.data;
    });
});

Так что его можно получить как weatherToolsInstance.getWeather().then(...).Ожидается, что при таком использовании он будет высмеиваться с axios-mock-adapter.

...