我试图测试此功能,该功能通过数据库梳理所有未填充的货币交易并检查价格匹配。如果找到一个,则发生数据库调用以关闭交易增量交易者的余额。我从另一个函数传递了一个价格数组,这只是一系列API调用。这是有问题的功能:
function executeTrade(pricesArr) {
// currencies array must match up one-to-one with pricesArr array
const currencies = ['btc', 'ltc', 'eth', 'doge'];
let chosen;
// Pull trades from database
return Trade.find().then(dbTrades => {
console.log('foo')
// Get only open trades
const openTrades = dbTrades.filter(trade => trade.open);
openTrades.forEach(trade => {
const balance = `${trade.curr_bought}_balance`;
// Get price to compare
if (trade.curr_bought === 'usd') chosen = pricesArr[0];
else {
for (let i = 0; i < currencies.length; i++) {
if (trade.curr_bought === currencies[i]) {
chosen = pricesArr[i];
}
}
}
// Do math depending on buying BTC with USD or something else
if ((trade.curr_bought === 'usd' && trade.sold_amount >= (trade.bought_amount / chosen)) || (trade.sold_amount >= chosen * trade.bought_amount)) {
// Close trade order
return trade.update({$set: { "open": false }})
.then(() => {
// Update user's balance to reflect successful trade
return User.findOne({"_id": trade.owner}).then(user => {
user.update({
$set: {
[balance]: user[balance] + parseFloat(trade.bought_amount)
}
}).then(doc => {
res.json(doc);
}).catch(err => console.log(err));
}).catch(err => console.log(err));
});
}
});
});
};
我试图用这个测试代码测试它:
it('Executes a trade if the specified sell prices are greater than or equal to the reported VWAP', done => {
const pricesArr = [0.1, 1, 1, 1];
executeTrade(pricesArr);
app
.get(`/api/trades/?_id=${testTrade._id}`)
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200)
.end((err, res) => {
console.log(res.body);
expect(res.body[0].open).to.be.false;
done();
});
}); 问题是在测试中没有执行任何数据库调用。该函数和所有其他测试在调用Express服务器的上下文中正常工作,我使用它来在实际的Web应用程序上进行这些调用。
我甚至尝试在it()函数和out的上下文中执行一个简单的find操作,但是都没有执行。
我在这里错过了什么?
答案 0 :(得分:0)
因为executeTrade函数是异步执行的,所以不能保证它包含的异步调用将在下一个函数调用之前完成(即在测试中调用API)。尝试这样的事情:
executeTrade(pricesArr)
.then(() => {
// make api call and check expected
});
确保executeTrade返回的promise在运行&#34;然后&#34;的内容之前解决。块。此外,您将在forEach构造内返回promise,这意味着无法保证在executeTrade函数返回之前将保证承诺的结果。为了解决这个问题,我建议使用类似的模式:
return Promise.all(openTrades.map((trade) => {
// do stuff here
});
只有在地图功能中返回的所有承诺都履行或者其中一个承诺拒绝后,才能解决此问题。
最后,看起来你的executeTrades函数可能会多次调用res.json()。您不能多次回复同一个请求,而且我也不会看到您的函数中定义了res的位置,因此也许可以避免。
谷歌在承诺上有一个很好的guide,我建议你看一下。