我正在尝试模拟来自NodeJS express的对外部服务的调用。我无法获得axios-mock-adapter来拦截实际的axios调用(http://api.openweathermap.org)并返回模拟的响应。断言完成后,它会失败,因为to值不同。来自呼叫的温度是实际的外部温度,而不是模拟的温度。不知道我是否已经完全离开或者是否要接近无法看到的解决方案。对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';
答案 0 :(得分:1)
问题出在经过测试的代码中。预计getWeather
成员是一种获取天气的方法,而它是promise属性。没有天气,实际上是天气。由于它是prototype
属性,因此它会急切地对类定义执行请求,即,在导入类后立即执行。这也意味着即使将来有必要也无法更新数据。
由于请求是急切执行的,因此不会受到Axios模拟的影响。
getWeather
也使用了promise构造反模式; 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
一起模拟。