带有nodejs的mocha断言挂起/超时断言(false)而不是错误 [英] mocha with nodejs assert hangs/timeouts for assert(false) instead of error

查看:116
本文介绍了带有nodejs的mocha断言挂起/超时断言(false)而不是错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这种摩卡测试:

describe 'sabah', →
    beforeEach →
        @sabahStrategy = _.filter(@strats, { name: 'sabah2' })[0]
            .strat

    it 'article list should be populated', (done) →
        @timeout 10000
        strat = new @sabahStrategy()
        articles = strat.getArticleStream('barlas')
        articles.take(2).toArray( (result)→
            _.each(result, (articleList) →

                // I make the assertions here
                // assert(false)
                assert(articleList.length > 1)
            )
            done()
        )

问题是每当我执行 assert(false)时,测试会挂起,直到超时,而不是给出断言错误,为什么?

The problem is, whenever I do assert(false), the test hangs until the timeout, instead of giving an assertion error, why?

编辑:

例如,如果我有这两项测试

For example if I have these two tests

    it 'assert false', (done) →
        assert(false)
        done()

    it 'article link stream should be populated', (done) →
        @timeout 20000
        articles = @sabahStrategy.articleLinkStream('barlas')
        articles.pull((err, result)→
            console.log('here')
            assert(false)
            console.log('after')
            assert(!err)
            assert(result.length > 1);
            _.each(result, (articleList) →
                assert(articleList.link)
            )
            done()
        )

第一个,按预期给出断言错误,第二个,在此处记录 ,并挂起断言(false)所以从未记录。它与文章有关,它们是一个流,而断言是在 pull 回调中,这是来自< a href =http://highlandjs.org/ =noreferrer> highland.js API 。

The first one, gives the assertion error as expected, the second one, logs here, and hangs at assert(false) so after is never logged. It has something to do with articles being a stream and the assertion is within a pull callback, this is from the highland.js API.

解决了编辑

所以根据Paul我解决了这段代码的问题:

So according to Paul I fixed the problem with this code:

    it 'article stream should be populated', (done) →
        @timeout 30000
        articles = @sabahStrategy.articleStream('barlas')

        articles.pull((err, result) →
            try
                # assert false properly throws now.
                assert(false)
                assert(!err)
                assert(result.length == 1)
                assert(result[0].body)
                assert(result[0].title || result[0].title2)
                done()
            catch e
                done(e)
        )

Edit2

我已经制作了问题的简化版本:

I've produced a simplified version of the problem:

h = require('highland')
Q = require('q')

describe 'testasynchigh', →
    beforeEach →
        @deferred = Q.defer()
        setTimeout((→
            @deferred.resolve(1)
        ).bind(this), 50)


    it 'should throw', (done) →
        s = h(@deferred.promise);
        s.pull((err, result) →
            console.log result
            assert false
            done()
        )

我看到你的版本确实可以运行@Louis,但如果你将promises纳入混合,mocha无法解决问题,所以它会挂起在这个例子中。还可以尝试注释断言false 并查看它是否通过。

I see your version does indeed work @Louis, but if you involve promises into the mix, mocha can't handle the problem, so it will hang in this example. Also try commenting out the assert false and see it passes.

所以路易斯我希望我能引起你的注意,你能解释一下这个问题吗?尝试捕捉看起来确实很难看我希望你找到一个合理的解决方案。

So Louis I hope I got your attention, could you explain the problem, and try catch looks ugly indeed and I hope you find a reasonable solution to this.

推荐答案

因为这就是你要告诉你的想法,当你添加'完成'回调。

Because that's what you're telling it you want to do, when you add the 'done' callback.

实际执行此测试的方法是调用 return done(错误)如果断言失败,则err是您要报告的任何字符串或错误对象。

The way to actually do this test is to call return done(err) if the assertion would fail, where err is any string or error object you want reported.

首先,当您的断言失败时,程序抛出异常并且永远不会达到 done(),这就是为什么你没有看到完成被调用。这是断言应该如何工作,但是因为你处于异步测试中,结果是回调永远不会触发,这就是你达到超时的原因。

First, when your assertion fails, the program throws an exception and never reaches done(), which is why you're not seeing done get called. This is how assertions are supposed to work, however since you're in an async test, the result is that the callback never fires, which is why you hit the timeout.

其次,正如我的原始答案所说错误是您要从测试中发出的任何错误。它可以是字符串错误消息或完整的Error对象子类。您创建它然后将其传递给 done()以指示测试失败。

Second, as my original answer said err is any error you want to send out from the test. It can be a string error message or a full-on Error object subclass. You create it and then pass it to done() to indicate the test failed.

更好的结构方式您在异步测试中的代码是将您的测试用作简单的布尔值,而不是断言。如果你真的想使用assert,那么将它包装在 try..catch 中。以下是几个例子:

The better way to structure your code in an asynchronous test is to use your tests as simple booleans, rather than as assertions. If you really want to use assert, then wrap it in a try..catch. Here's a couple examples:

if(err) return done(err); // in this case, err is defined as part of the parent callback signature that you have in your code already.

if(result.length < 1) return done('Result was empty!'); 

最后,如果你真的想要断言 ,那么你可以:

Finally, if you really want to assert, then you can:

try{
  assert(!err);
}catch(e){
  return done(e);
}

我正在调用 return done(err)而不是 done(错误)因为它会停止执行其余的代码,这通常是你想要的。

I'm calling return done(err) rather than done(err) because it stops the rest of the code from executing, which is normally what you want.

这篇关于带有nodejs的mocha断言挂起/超时断言(false)而不是错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆