包装在Mocha中正确工作测试所需的setTimeout

时间:2016-06-18 19:17:52

标签: javascript node.js asynchronous mocha settimeout

我正在为我的Node应用程序编写测试

'use strict';
const babelRegister = require('babel-register');
const babelPolyfill = require('babel-polyfill');
const chai = require('chai');
const sinon = require('sinon');
chai.should();
const bcrypt = require('bcryptjs');
const mongoose = require('mongoose');
const passport = require('passport');
const localStrategy = require('passport-local');

describe('test', function () {

    beforeEach(function (done) {
        if (mongoose.connection.readyState === 0) {
            mongoose.connect('mongodb://localhost:27017/clearanceForm-test', function () {
                console.log("mongodb test connection open");
                done();
            });
        }
    });

    afterEach(function () {
        console.log("test finished");
    });

    it('logs in', function (done) {
        let Schema = mongoose.Schema;
        let test_schema = new Schema({
            username: String,
            password: String,
            group: {type: String, enum: ['clearance_unit_managers', 'clearance_unit_admins']}
        });
        let test_model = mongoose.model('test', test_schema);

        (async function example() {

            const unhashedPassword = Math.random().toString(36);
            const passed = {
                username: Math.random().toString(36),
                password: bcrypt.hashSync(unhashedPassword),
                group: 'clearance_unit_managers'
            };

            let saved = await new test_model(passed).save();
            let found = await test_model.findOne({username: saved.username}).exec();
            setTimeout(function () {
                found.username.should.not.equal(passed.username);
                done();
            });

        })();
    });

});

在代码的末尾你可以看到我提交了包装断言,它应该故意在setTimeOut中失败 - 否则(当我从setTimeout拉出断言时)我得到错误:超过2000ms的超时。 如果我没有完成()测试,如果通过。 如果断言是真的那么一切正常......

断言失败是否在任务队列中作为最后执行,不知何故在done()之后已经在堆栈中执行。

有人可以向我解释一下吗? 在此先感谢:)

1 个答案:

答案 0 :(得分:1)

使用async / await的相当有创意的方法会吞下断言引发的异常,这会导致done()永远不会被调用,测试会超时。

您可以将整个测试功能改为异步:

it('logs in', async () => {
  ...
  let found = await test_model.findOne({username: saved.username});
  found.username.should.not.equal(passed.username);
});

或者明确捕获断言异常并使用错误调用done()

try {
  found.username.should.not.equal(passed.username);
  done();
} catch(e) {
  done(e);
}

(这很难看)