【问题标题】:Mocha promise test timout摩卡承诺测试超时
【发布时间】:2018-08-06 17:24:44
【问题描述】:

我在 NodeJS 中有以下测试代码:

'use strict';

// Example class to be tested
class AuthController {

    constructor() {
        console.log('Auth Controller test!');
    }

    isAuthorizedAsync(roles, neededRole) {
        return new Promise((resolve, reject) => {
            return resolve(roles.indexOf(neededRole) >= 0);
        });
    }
}

module.exports = AuthController;

以及以下mocha测试代码:

'use strict';

const assert         = require('assert');
const AuthController = require('../../lib/controllers/auth.controller');

describe('isAuthorizedAsync', () => {
    let authController = null;

    beforeEach(done =>  {
        authController = new AuthController();
        done();
    });

    it('Should return false if not authorized', function(done) {
        this.timeout(10000);    

        authController.isAuthorizedAsync(['user'], 'admin')
            .then(isAuth => {
                assert.equal(true, isAuth);
                done();
            })
            .catch(err => {
                throw(err);
                done();
            });
    });    
});

这会引发以下错误:

 1 failing

1) AuthController
    isAuthorizedAsync
      Should return false if not authorized:
  Error: Timeout of 10000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (c:\supportal\node_modules\ttm-module\test\controllers\auth.controller.spec.js)

我已尝试将默认 mocha 测试超时时间增加到 10 秒,并确保承诺得到解决。我是摩卡的新手。我在这里遗漏了什么吗?

【问题讨论】:

  • 据我了解,Mocha 配置没有问题。您需要先在测试用例中解决 Promise,然后才能测试您的套件
  • 是的,我确保通过控制台在 .then() 块中注销测试消息来解决承诺。似乎仍然出现此错误,所以不确定..
  • 像这个 spyOn(authController, 'isAuthorizedAsync').and.returnValue(Promise.resolve(true));
  • 我发现了一种使用 chai-as-promised 的解决方法,如这篇 SO 帖子中所述:stackoverflow.com/questions/26571328/…。这是正确的方法吗?
  • chai-as-promised 主要是为那些不想在测试中做很多承诺链的人提供便利。你当然不需要它。您可以使用它,但我建议您确保您也了解如何正常使用它。

标签: javascript node.js testing mocha.js


【解决方案1】:

这里的问题是您没有正确使用mocha async API。要导致 done 回调失败,您应该在调用它时提供错误作为第一个参数。

正如所写,您在then 处理程序中的断言会抛出,它会跳过第一个done 调用并转到catch 处理程序。 catch 处理程序又会重新抛出相同的错误,同样会阻止您到达第二个 done 回调。

您得到的是未处理的 Promise 拒绝并且没有调用 done,导致 mocha 测试超时,可能带有关于未处理拒绝的警告消息,具体取决于您使用的节点版本。

最快的解决方法是正确使用 done 回调:

it('Should return false if not authorized', function(done) {
    authController.isAuthorizedAsync(['user'], 'admin')
        .then(isAuth => {
            assert.equal(true, isAuth);
            done();
        })
        .catch(err => {
            done(err); // Note the difference
        });
});

更简洁的解决方法是通过返回链式承诺来使用 Mocha 的内置承诺支持。这消除了显式处理失败案例的需要:

it('Should return false if not authorized', function() {
    return authController.isAuthorizedAsync(['user'], 'admin')
        .then(isAuth => {
            assert.equal(true, isAuth);
        });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-24
    • 2022-11-27
    • 2019-06-13
    • 1970-01-01
    • 2017-06-23
    • 2018-11-13
    • 2015-05-23
    相关资源
    最近更新 更多