Макетируйте запрос axios для внешнего сервиса в тесте
Я пытаюсь издеваться над внешним сервисом NodeJS Express. Я не могу заставить axios-mock-adapter перехватить реальный вызов axios ( http://api.openweathermap.org/) и вернуть поддельный ответ. Когда утверждение сделано, оно терпит неудачу, потому что значения отличаются. Температура от вызова - фактическая наружная температура, а не поддельная. Не знаю, полностью ли я выключен или я близок к решению, которое я не вижу. Вид нового для JavaScript и NodeJS.
Пожалуйста, Stackru, ты моя единственная помощь.
Это мой код:
Файл для проверки:
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 ответ
Проблема в проверенном коде. Ожидается, что getWeather
member - это метод, который получает погоду, а это свойство обещания. Погода не получается, на самом деле погода. Так как это 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
при использовании так.