mocha с NodeJS assert зависает / таймауты для assert (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)
, тест зависает до таймаута, вместо того, чтобы давать ошибку утверждения, почему?
Edit:
например, если у меня есть эти два теста
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()
)
первый, дает ошибку утверждения, как и ожидалось, второй, logs here
, и зависает на assert(false)
так after
никогда не регистрируется. Это как-то связано с articles
будучи потоком, и утверждение находится в пределах pull
обратный вызов, это из Хайленд.С. API.
Решил Изменить:
Итак, согласно Павлу I Исправлена проблема с этим кодом:
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:
я подготовил упрощенную версию проблемы:
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, но если вы включаете обещания в микс, мокко не может обработайте проблему, чтобы она зависала в этом примере. Также попробуйте закомментировать assert false
и смотрите, как это проходит.
Итак, Луис, надеюсь, я привлек ваше внимание, не могли бы вы объяснить проблему, и try catch
действительно выглядит некрасиво и я надеюсь, что вы найдете разумное решение этого.
3 ответов
потому что это то, что вы говорите, что хотите сделать, когда вы добавляете обратный вызов "готово".
способ на самом деле сделать этот тест-позвонить return done(err)
если утверждение потерпит неудачу, где err-это любая строка или объект ошибки, о котором вы хотите сообщить.
во-первых, когда ваше утверждение не удается, программа выдает исключение, и никогда не достигает done()
, именно поэтому вы не видите, что сделано. Вот как должны работать утверждения, однако, поскольку вы находитесь в асинхронном режиме тест, результат заключается в том, что обратный вызов никогда не срабатывает, поэтому вы нажимаете тайм-аут.
во-вторых, как сказал мой первоначальный ответ err
ошибка, которую вы хотите отправить из теста. Это может быть строковое сообщение об ошибке или подкласс объекта full-on Error. Вы создаете его, а затем передаете его done()
чтобы указать, что тест не удался.
лучший способ структурировать код в асинхронном тесте-использовать тесты как простые логические значения, а не как утверждения. Если вы действительно хотите использовать assert, а затем оберните его в try..catch
. Вот несколько примеров:
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!');
наконец, если вы действительно хотите assert
, то вы можете:
try{
assert(!err);
}catch(e){
return done(e);
}
Я звоню return done(err)
, а не done(err)
потому что он останавливает выполнение остальной части кода, что обычно является тем, что вы хотите.
когда я использую Highland.js с супер простым тестом, Мокко ловит неудачное утверждение без каких-либо проблем:
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();
});
});
});
это говорит о том, что проблема в вашем примере не Мокко, ни Хайленд.js. Если
для тех, у кого такая же проблема: вы должны убедиться, что done()
вызывается даже после сбоя assert, как в следующем коде:
try {
// your asserts go here
done();
} catch (e) {
done(e);
}