如何使用Mocha / Chai测试Mongoose CRUD操作?

时间:2018-02-23 20:42:17

标签: node.js express mongoose mocha chai

我试图测试此功能,该功能通过数据库梳理所有未填充的货币交易并检查价格匹配。如果找到一个,则发生数据库调用以关闭交易增量交易者的余额。我从另一个函数传递了一个价格数组,这只是一系列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操作,但是都没有执行。

我在这里错过了什么?

1 个答案:

答案 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,我建议你看一下。