简体   繁体   English

在Mocha中正常工作测试需要包装setTimeout

[英]Wrapping in setTimeout required for properly working test in Mocha

Im writing tests for my Node app 我正在为我的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();
            });

        })();
    });

});

at the end of the code you can see that I hand to wrap assertion which should fail on purpose in setTimeOut - otherwise (when I pull assertion from setTimeout) I just get Error: timeout of 2000ms exceeded. 在代码的末尾,您可以看到我包装了断言,该断言应该故意在setTimeOut中失败-否则(当我从setTimeout中提取断言时)我只会得到错误:超时超过2000ms。 If I do it without done() test if passing. 如果我没有执行done()进行测试,则是否通过。 If assertions are true then everything works ok... 如果断言是正确的,那么一切正常。

Is it like assertion failure is executed as last in task queue, somehow after done() was already executed in stack. 就像断言失败是最后执行在任务队列中一样,在堆栈中已经执行了done()之后。

Could someone explain this to me? 有人可以向我解释吗? Thanks in advance :) 提前致谢 :)

Your rather creative way of using async/await swallows the exception thrown by the assertion, which causes done() never to get called and the test to time out. 您使用async / await的颇具创意的方式会吞没断言引发的异常,这将导致done()永不被调用且测试超时。

You can make the entire test function async instead: 您可以改为使整个测试函数异步:

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

Or catch the assertion exception explicitly and call done() with the error: 或显式地捕获断言异常,并使用以下错误调用done()

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

(which is ugly) (很丑)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM