2015-12-02 6 views
0

Почему этот тест не срабатывает, говоря, что шпиона onSuccess так и не был вызван?Почему этот асинхронный тест Жасмин не работает?

it('should correctly call the success callback',function(done) 
{ 
    const callbacks={ 
     onSuccess:function() 
     { 
      console.log('OK'); 
      done(); 
     }, 
     onError:function() 
     { 
      console.log('ERR'); 
      done(); 
     } 
    }; 

    spyOn(callbacks,'onSuccess').and.callThrough(); 
    spyOn(callbacks,'onError').and.callThrough(); 

    doSomethingAsync(callbacks.onSuccess,callbacks.onError); 

    expect(callbacks.onSuccess).toHaveBeenCalled(); 
    expect(callbacks.onError).not.toHaveBeenCalled(); 
}); 

При выполнении теста, я получаю сообщение об ошибке говорящее Expected spy onSuccess to have been called..
Прямо над этим, есть консольный журнал с надписью «ОК», что означает, что шпион был вызван и что он вызвал.

+1

Вызываемые вызовы 'expect()' _before_ 'doSomethingAsync()' завершены, поэтому вам нужно как-то дождаться окончания. – robertklep

+0

Хм, не дождаться, когда 'done()' будет вызван до оценки ожиданий? – Francisc

+1

Нет, вызывая 'done' сигналы о завершении теста (включая любые утверждения). – robertklep

ответ

1

Трудно утверждать, что один обратный вызов вызван, а другой не без обрезания doSomethingAsync или его внутренних компонентов.

Вот надуманный крайний случай:

function doSomethingAsync(onSuccess, onError) { 
    setTimeout(function() { 
    onSuccess('hello'); 
    }, 500); 
    setTimeout(function() { 
    onError(new Error('foo')); 
    }, 1000); 
} 

(так она называет onSuccess после полсекунды, и onError после второй)

Если вы утверждаете, в onSuccess обработчиком, что onError hasn» t, тест пройдет, хотя onError- вызов (хотя и через полсекунды позже).

Это то, с чем вы не можете легко обойтись, если только (как указано ранее) вы не заглушаете (внутренности) doSomethingAsync.

Если вы просто хотите проверить, если doSomethingAsync называет правильный обработчик, вы можете сократить свой тестовый пример для этого (при условии, что это не является строго необходимым для вызова обработчиков в вашем callbacks объекта):

it('should correctly call the success callback',function(done) { 
    doSomethingAsync(done, done.fail); 
}); 

(это не улавливает doSomethingAsync, вызывая как обработчики, если он называет onSuccess до onError, тест пройдет).

+0

Спасибо. [extra chars] – Francisc

+0

Я думаю, что здесь у меня что-то не хватает, но ваш ответ говорит о том, чтобы пропустить тему теста. Если ваше тестирование doSomethingAsync и вы заглушите эту функцию, что вы тестируете, кроме заглушки? – Stewart

+0

@ Стюарт да, формулировка не велика. Я имел в виду, что, принимая мой надуманный пример, может потребоваться заглушить 'setTimeout', чтобы проверить работу' doSomeThingAsync'. Для того, чтобы тестировать некоторую функцию _other_, которая полагается на нее, может потребоваться полное удаление 'doSomethingAsync'. – robertklep

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