【问题标题】:Unit testing nodejs events单元测试nodejs事件
【发布时间】:2014-01-27 22:45:37
【问题描述】:

我正在使用this answer 中解释的解决方案对我的节点应用程序中的事件进行单元测试。

但是,setTimeout 函数从不调用,因此我的测试在应该失败时通过了。

这是一个例子:

suite('myTests', function() {
    test('myFunction_whenCalled_emitsEvent', function() {
        var myClass = new MyClass();
            var eventTimeout = setTimeout(function() {
                assert(false);
            }, 1000);
            myClass.on('something', function() {
                clearTimeout(eventTimeout);
            });
            myClass.doSomething(); // this does not emit the 'something' event
    });
});

我预计这会在 1 秒后失败,只要不引发“某事”事件。

我在assert(false) 行中放了一个断点,它永远不会被命中。

有人能指出我正确的方向吗?谢谢。

【问题讨论】:

    标签: javascript node.js unit-testing events mocha.js


    【解决方案1】:

    您必须使用done 回调来表明您的测试已完成。像这样的:

    suite('myTests', function() {
        test('myFunction_whenCalled_emitsEvent', function(done) {
            var myClass = new MyClass();
            myClass.on('something', function() {
                done();
            });
            myClass.doSomething();
        });
    });
    

    看起来您只是在测试是否发出事件。如果是这种情况,那么整个setTimeout 事情就没有必要了。如果在没有默认超时(2000 毫秒,如果我没记错的话)的情况下无法获得 done,Mocha 本身就会超时。

    按照您的代码设置方式,Mocha 只会安排您的活动,然后退出测试。由于调度事件是成功的,Mocha 将调用测试成功。

    【讨论】:

    • 你好路易斯。谢谢你的回答。我更改了代码,但 don() 调用未按预期命中,但测试仍然通过。看起来所有测试都在大约 12 毫秒后运行并退出。我需要做些什么来确保它在退出之前检查 done() 吗?再次感谢您。
    • 实际上,我认为问题出在其他方面。如果测试通过了我在答案中的代码,那么这意味着 done() is 被调用,因为如果在超时内没有调用 done(),Mocha 抱怨时期。现在,如果在其他地方(在您的应用程序或您正在使用的库中)有 setTimeout 执行的操作,那么这可能会延迟 Mocha 的退出。
    • 如果我在此测试之前运行了使用 setTimeout 的测试,但没有调用 done,这会导致此问题吗?
    • 可能,但从这里很难说。您可以做的一件事是将这个测试隔离在一个单独的文件中并在其上运行 mocha 并查看它的行为。如果它运行文件并且在退出之前没有延迟,那么您就知道问题出在其他地方。
    • 感谢您对此的持续支持!我会在你的帮助下继续调查。