Mocha with nodejs assert hangs / timeouts for assert (false) instead of error

I have such a mocha test:

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() ) 

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

Edit:

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() ) 

The first one gives an assertion error, as expected, the second one, logs here and hangs on assert(false) , so after never logged. This is because articles is a stream and the statement is in the pull callback, this is from the highland.js API .

Decided to Change :

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 created 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() ) 

I see that your version really works @Louis, but if you include promises in the mix, mocha will not be able to deal with this problem, so it will hang in this example. Also try commenting on assert false and see how it goes.

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

+6
source share
3 answers

Because what you say you want to do when you add a done callback.

The way to run this test is to call return done(err) if the statement fails, where err is any line or error object that you want to report.

First, when your statement fails, the program throws an exception and never reaches done() , so you do not see the called call. This is how statements should work, however, since you are in an asynchronous test, the result is that the callback never works, so you press the timeout.

Secondly, since err my original answer - this is any error you want to send from the test. This can be a string error message or a full subclass of the Error object. You create it and then pass it to done() to show that the test failed.

The best way to structure your code in an asynchronous test is to use your tests as simple Booleans, not statements. If you really want to use assert, then wrap it in try..catch . Here are some 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 assert , you can:

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

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

+7
source

When I use Highland.js with a super simple test, Mocha catches a failed statement without any problems:

 var _ = require("highland"); var fs = require("fs"); var assert = require("assert"); describe("test", function () { it("test", function (done) { var s = _([1, 2, 3, 4]); s.pull(function (err, result) { console.log(result); assert(false); done(); }); }); }); 

This suggests that the problem in your example is not Mocha, nor Highland.js. If the articleLinkStream object (or articleSream , which apparently changes from fragment to fragment) is custom code, or maybe this code is a bug and actually catches exceptions rather than letting them move up the stack.

0
source

For those who have the same problem: you must make sure that done() is called even after assert fails, as in the following code:

 try { // your asserts go here done(); } catch (e) { done(e); } 
0
source

Source: https://habr.com/ru/post/977801/


All Articles