为什么mocha会在与restify和knex一起使用时超时?

时间:2016-08-25 19:39:16

标签: node.js mocha restify supertest

我目前正在使用mocha 2.5.3,supertest 2.0.0,knex 0.11.10,restify 4.1.1和sqlite3 3.1.4。

我有以下非常简单的restify服务器:

const restify = require('restify');
const knex = require('knex')({
  client: 'sqlite3',
  connection: {
    'filename': 'test.db'
  }
});

const app = restify.createServer();

app.get('/', (req, res, next) => {
  knex.select().from('nonexistent_table')
  .then((rows) => {
    return res.json(rows);
  })
  .catch((err) => {
    return res.send('error');
  });
});
module.exports = app;

以下测试将导致测试在2000ms超时而不是失败:

const assert = require('assert');
const supertest = require('supertest');
const app = require('./app');

describe('GET /', function () {

  it('should not timeout', function (done) {
    supertest(app)
    .get('/')
    .end(function(err, res) {
      assert(false);
      done();
    });
  });
});

如果对knex的调用已完成而不是被拒绝,则测试将失败并且不会超时。仅当knex呼叫被拒绝时才会出现超时。

有没有人想过可能导致超时的原因而不是正确的失败?

编辑:我尽可能调试了这个,当mocha尝试生成堆栈跟踪时,似乎超时发生了。

2 个答案:

答案 0 :(得分:1)

supertest在幕后使用superagentsuperagent支持承诺。 (搜索.then here。)因此,您可以使用.then代替.end,只返回承诺,而不是使用done

  it('should not timeout', function () {
      return supertest(app)
          .get('/')
          .then(function(res) {
              assert(false);
          });
  });

当我将上述代码与问题中的其余代码一起使用时,我就会失败。

至于为什么使用done不起作用,我不清楚。可能是supertestsuperagent吞下了传递给.end()的回调中引发的异常。如果吞下异常,则Mocha无法检测到它们。然后,您必须自己捕获由失败的断言引发的异常,并将它们传递给done。我更喜欢使用承诺。

答案 1 :(得分:0)

尝试更改第一行: bluebird.resolve(knex.select().from('nonexistent_table'))

你还需要在顶部要求'蓝鸟'。它将解决一个问题,为您提供有关错误的上下文

我认为选择问题:你忘了参数