2014-01-15 6 views
7

У меня есть угловая служба, которая делает некоторые асинхронные вещи (на основе таймеров). Одна из вещей, которые вы можете сделать с помощью таймера определить «обработчик», который стреляет по истечении таймера (как в этом псевдо-код):Угловая + Карма: Тестирование асинхронных функций

flag = false; 
timer = new Timer(1000); // ms 
timer.handler = function() { flag = true }; 

В этом тривиальном случае таймер будет установлен флаг верно через 1 секунду. Как я могу проверить это с помощью углового/кармы/жасмина?

От чтения документации, я ожидал бы, чтобы это работало:

... 
flag = false; 
timer = new Timer(1000); 
timer.handler = function() { flag = true }; 
expect(flag).toBe(false); 
sleep(2) 
expect(flag).toBe(true); 
... 

Вместо того, чтобы быть морально в вертикальном положении, что тест решил потерпеть неудачу с этим:

ReferenceError: Can't find variable: sleep 

После некоторого чтения, по-видимому, Я не могу использовать угловой сценарий с Жасмином. Хорошо, я в порядке.

ОБНОВЛЕНИЕ: В комментариях я опробовал свой «рабочий» метод установления. Его никогда не называют.

Так это работает:

... 
flag = false; 
timer = new Timer(1000); 
timer.handler = function() { flag = true }; 
expect(flag).toBe(false); 
setTimeout(function() { expect(flag).toBe(true) }, 2000); 
... 

Но чувствует себя немного странно.

Вопрос: Есть ли лучший способ?

Fun Trivia: Да, я знаю около $ таймаута. У меня есть очень хорошие причины (TM) для того, чтобы делать то, что я делал глубоко в кодовых шахтах, вдали от дневного света =)

+0

Почему стандартный тайм-аут кажется странным? – rdodev

+0

, если вы должны использовать $ timeout, вы могли бы назвать $ timeout.flush(); с этим вы можете протестировать условия предварительного таймера и условия посттаймера. Но вы этого не хотите :) – michael

+0

@rdodev: Ну, я не знаю, почему это было странно раньше, но я только что протестировал, и ожидание() внутри таймаута фактически не вызвано (я установил время до 10 секунд и повторить тест, но он завершился почти сразу). –

ответ

11

У Жасмина есть способ сделать асинхронное тестирование с помощью waitits() или waitsFor() и пробеги(). Посмотрите here.

Код будет что-то вроде:

... 
flag = false; 
timer = new Timer(1000); 
timer.handler = function() { flag = true }; 
expect(flag).toBe(false); 
waitsFor(function() { 
    return flag; 
}, "timer ran"); 
runs(function() { 
    expect(flag).toBe(true); 
}); 
... 

Примечание от OP

Это правильное решение, так что я пометил его как принято. Я на самом деле закончил реализацию метода сна, основанного на этом решении, и хотел поделиться, если он был полезен другим.

В тестовом файле:

function loiter(ms) { 
    var loiter = true; 
    setTimeout(function() {loiter = false}, ms); 
    waitsFor(function() {return !loiter}, "Loitered too long", ms + 50); 
} 

it("should ...", function() { 
    flag = false; 
    timer = new Timer(1000); 
    timer.handler = function() {flag = true}; 
    setTimeout(function() {expect(flag).toBe(true)}), 1100); 

    loiter(1200); 
}) 

Я надеюсь, что это полезно! Я оставлю это как упражнение для читателя, чтобы понять, почему я сделал это таким образом =)

+0

Это правильный ответ. Майкл ответил первым в комментариях выше, но если он не даст ответ в ближайшее время, я соглашусь с вами как правильно. Спасибо =) –

+3

«Я оставлю это как упражнение для читателя, чтобы понять, почему я сделал это таким образом =)« Было бы неплохо, если бы вы закончили объяснять. –

+0

'setTimeout (function() {ожидать (флаг) .toBe (true)}), 1100);' должно быть 'setTimeout (function() {ожидать (флаг) .toBe (true)}, 1100);' - работает Великий! :-) –

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