2013-11-11 2 views
12

я тестирование модели банка у меня есть следующие:Mocha/Chai асинхронные тесты «Done()» Fn не работает

describe('Bank Model - Ajax', function() { 

    it('loads bank', function (done) { 

     var bank = new Bank(); 

     bank.OnLoaded = _(function() { 
      expect(this.id).to.eql(1171); 
      expect(true).to.eql(false); 
      done(); 
     }).bind(bank); 

     bank.load(1171); 


    }); 
}); 

Вызов нагрузки делает AJAX запрос на моем сервере. Моя проблема в том, что expect(true).to.eql(false); выбрасывает Uncaught Assertion Error, и я не уверен, почему. Я использую рекомендованную стратегию Mocha для завершения моего тестового примера. Я делаю это неправильно?

Спасибо.

+3

Гм, вы ожидали 'истинный === false'? –

+1

@muistooshort точка заключается в том, что утверждение должно быть уловлено тестовым случаем; это не должно быть нечеткой ошибкой. – khalid13

+0

Но разве «ожидание ...» не вызывает исключение, если утверждение не выполняется? Я не эксперт в Mocha или Chai, так что, может быть, мне не хватает чего-то очевидного. –

ответ

9

Вы ничего не делаете неправильно. Мокко нелегко поймать исключения, которые бросаются в обратный вызов, так как они выполняются после завершения тестовой функции, поэтому любые неудачные утверждения - это нестатические фатальные ошибки, а не хорошие различия, которые вы обычно получаете с синхронным кодом.

Люди работают над обходными методами, такими как providing a custom method that assertion libraries can call instead of throwing, или using Node Domains when running in Node. Но пока кажется, что он по-прежнему не ведет себя идеально.

Поскольку метод done принимает единственный параметр, содержащий ошибку, вы можете добавить код в свой тест, чтобы перехватывать исключения в обратном вызове и передавать их в done(err) внутри блока catch. Но это будет довольно грязно.

Может уменьшить повторение с какой-то вспомогательной функции как ниже:

function catching(done, fn) { 
    try { 
    fn(); 
    done(); 
    } catch(err) { 
    done(err); 
    } 
} 

А потом:

bank.OnLoaded = catching(done, _(function() { 
    expect(this.id).to.eql(1171); 
    expect(true).to.eql(false); 
}).bind(bank)); 
+0

Спасибо за ваш ответ. Я предположил, что, поскольку обратный вызов упоминается внутри вызова it(), тогда он() fn не удаляется из памяти, потому что где-то есть ссылка на этот обратный вызов. Это неточно? – khalid13

+0

С точки зрения памяти, да, закрытие функции it() поддерживается, так как обратный вызов внутри него. Но обратный вызов _invoked_ вне функции it(), поэтому он не может поймать никаких исключений традиционным способом. К моменту возникновения исключения функция it() уже завершена. – Nick

Смежные вопросы