1

我正在尝试模拟从 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';
4

1 回答 1

1

问题出在经过测试的代码中。预计getWeathermember 是一种获取天气的方法,而它是 promise 属性。它没有天气,它实际上是天气。由于它是prototype属性,它急切地执行对类定义的请求,即一旦导入类。这也意味着将来无法更新数据,即使需要这样做。

由于请求是热切执行的,因此不会受到 Axios mock 的影响。

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时会被嘲笑。

于 2018-09-27T12:34:02.020 回答