我正在开发Express.js应用。当前功能是创建与发布请求的约会,从第三方API获取和保存数据,然后在后续请求中发送更新的API数据。该功能完全正常,但在测试中,不会调用获取API数据的功能。
创建约会的路线:
app.post('/schedule', requestHandler.postSchedule);
创建约会的请求处理程序:
requestHandler.postSchedule = function (req, res) {
let appointment = {
// posted data
};
new Appointment(appointment)
.save()
.then(newAppointment => {
if(req.body.cityName && req.body.cityName !== '') {
console.log('req.body.cityName', req.body.cityName);
weatherHelper.addNewCityWeatherData(req.body.cityName);
}
return newAppointment;
})
.then(newAppointment => {
// do some other stuff
res.send(newAppointment);
})
.catch(err => {
error(err);
});
};
添加天气数据的功能:
exports.addNewCityWeatherData = (city) => {
console.log('City in addNewCityWeatherData', city);
getCurrentTrackingCities(cities => {
if(cities.indexOf(city) < 0) {
console.log(city + ' data not in weather');
getWeatherData(city, data => {
console.log('Got weather data');
addWeatherDataToDB(city, data);
});
} else {
console.log('City exists');
}
});
};
从API获取天气数据的功能:
getWeatherData = (city, callback) => {
console.log('getWeatherData called', city);
let url = `http://api.apixu.com/v1/forecast.json?key=${weatherApiKey}&q=${city}&days=${10}`
request(url, (err, res, body) => {
console.log('Weather data received body');
callback(body);
});
};
测试时,此功能会失败,并且除了“收到气象数据的正文”以及后续功能中的日志外,还会打印所有控制台日志。
这是我的测试:
describe.only('Weather data', function() {
let requestWithSession = request.defaults({jar: true});
let hashedPass = bcrypt.hashSync('testpass', null);
beforeEach((done) => {
new User({
'name': 'Test User',
'email': 'testuser@test.com',
'password': hashedPass
})
.save()
.then(() => {
let options = {
'method': 'POST',
'uri': testHost + '/login',
'form': {
'email': 'testuser@test.com',
'password': 'testpass'
}
};
requestWithSession(options, (err, res, body) => {
done();
});
});
}); // beforeEach
afterEach((done) => {
// remove test stuff from db
}); // afterEach
it('Adds weather data when an appointment with new city is posted', (done) => {
let options = {
'method': 'POST',
'uri': testHost + '/schedule',
'form': {
'title': 'Test title',
'description': 'Test description',
'start_date_time': '2017-07-19 01:00',
'end_date_time': '2017-07-19 02:00',
'cityName': 'New York',
'isTrackingWeather': 'true'
}
};
// post request to add appointment data
requestWithSession(options, (err, res, body) => {
if(err) {
console.log('DatabaseError in Weather Data');
throw {
type: 'DatabaseError',
message: 'Failed to create test setup data'
};
}
let options = {
'method': 'GET',
'uri': testHost + '/allweather'
};
// subsequesnt request to get updated weather data
requestWithSession(options, (err, res, body) => {
let found = false;
weatherData = JSON.parse(body);
// console.log('weatherData in test', weatherData);
weatherData.forEach(weather => {
if(weather.location && weather.location.name === 'New York') {
found = true;
}
});
expect(found).to.be.true;
done();
});
});
});
}); // Weather Data
这是终端输出:
任何人都可以告诉我,我做错了什么?
答案 0 :(得分:1)
当您运行测试时,测试套件向您的测试服务器发出请求,并且在测试服务器中处理请求的代码会向另一个主机发出另一个请求。
您无法看到'Weather data received body'
,因为您的测试服务器处理的请求不是等待以获取测试服务器本身发出的请求。 addNewCityWeatherData
没有回调并且没有返回一个promise,因此调用它的代码会以愉快的方式进行,而不必等待它完成。您应该修改它以允许调用代码等待结果。
此外,我没有看到测试服务器发起的请求中的数据如何折叠回来自测试套件的请求。您可能还必须为此添加一些代码,除非addWeatherDataToDB(city, data);
以某种方式自动处理它。