2015-01-07 5 views
1

Я пытаюсь проверить значение, которое устанавливается асинхронно с использованием обратного вызова done() Jasmine 2.Jasmine Async Testing

Я основан мой тест по примеру Жасмин дает в своей документации (http://jasmine.github.io/2.0/upgrading.html#section-Asynchronous_Specs):

it('can set a flag after a delay', function(done) { 

    var flag = false, 
    setFlag = function() { 
    //set the flag after a delay 
    setTimeout(function() { 
     flag = true; 
     done(); 
    }, 100); 
    }; 

    setFlag(); 
    expect(flag).toBe(true); 
}); 

я получаю результат «Прогнозный ложь, чтобы быть правдой», так что я предполагаю, что это не дожидаясь завершения обратного вызова done() перед проверкой значения флага.

Кто-нибудь знает, почему этот тест терпит неудачу?

Спасибо!

ответ

4

Это потому, что вы используете свое утверждение, как только setTimeout был вызовом, поэтому вы не даете ему достаточно времени для вызова обратного вызова, который устанавливает флаг в true. Ниже код будет работать (запустить приведенный ниже код на TryJasmine, чтобы увидеть, как он ведет себя):

describe('flag delays', function() { 
    it('can set a flag after a delay', function(done) { 
    var flag = false, 
    setFlag = function() { 
     //set the flag after a delay 
     setTimeout(function() { 
      flag = true; 
      expect(flag).toBe(true); 
      done(); 
     }, 100); 
    }; 

    setFlag(); 
    }); 
}); 

Забегая вперед, Жасмин имеет метод waitsFor для облегчения тестирования таймеров. Еще лучше, Sinon.JS обеспечивает функциональность для faking times, что позволяет пропустить setTimeout invocations и проверить поведение, не создавая зависимостей, зависящих от продолжительности. Кроме того, вы сможете писать утверждения в конце своих тестов, как это было в вашем вопросе, что значительно улучшит читаемость.

+0

А я вижу. Я надеялся, что Jasmine 2 дал() дополнительные возможности, чтобы посмотреть, не стоит ли ждать завершения() обратного вызова. Похоже, добавление, сделанное в качестве параметра для него(), просто говорит ему ждать, пока не будет вызван done(), прежде чем перейти к следующему тесту. правильно? – corbin

+1

Sinon.js выглядит очень круто. Я тоже наткнулся на Jasmine.tick, который выглядит так, как будто он может издеваться над setTimeouts: http://jasmine.github.io/2.0/introduction.html#section-Mocking_the_JavaScript_Timeout_Functions – corbin

+0

@corbin. Верно. Я использовал его в своих тестах Mocha, поскольку эта структура поддерживает тот же подход. Для моего асинхронного материала я использую поддельные таймеры (которые, по общему признанию, я встречал только несколько дней назад!) И «Promise's», которые могут быть возвращены непосредственно тестировщику Mocha; это означает, что вам даже не нужно вызывать 'done'! Я не уверен, что Карма ведет себя одинаково. –

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