2012-06-19 4 views
2

Я просто даю попытку модульного тестирования в javascript/coffeescript с жасмином, очень приятно.jasmine.Clock VS sinon.clock Что случилось с моим jasmin.Clock.useMock() использованием?

Я пытался использовать jasmine.Clock.Mock() для того, чтобы заранее активировать обратные вызовы setTimeout.

Увы, у jasmine.Clock.tick (1001), похоже, не было никакого эффекта! Я тогда обнаружил sinon.js, у которого было свое собственное время, и используя это, все было в порядке. Я хотел бы понять, почему.

Вот фиктивная JQuery плагин для тестирования:

dummy_method = function(callback) { 
    fire_callback = function() { 
    callback(); 
    } 
    setTimeout("fire_callback()", 1000); 
} 

И вот обе версии спецификации:

# Working test (spy was called as expected), using sinon FakeTimers 
describe "jQuery.fn.countdown", -> 
    beforeEach() -> 
    this.clock = sinon.useFakeTimers(); 
    afterEach() -> 
    this.clock.restore() 
    it 'should fireup the callback', -> 
    countdown_callback = jasmine.createSpy('countdown_callback'); 

    dummy_method(countdown_callback) 
    this.clock.tick(1001) 
    expect(countdown_callback).toHaveBeenCalled() 



# Non-working test (spy is never called), using jasmine Clock Mock 
describe "jQuery.fn.countdown", -> 
    beforeEach() -> 
    jasmine.Clock.useMock() 
    it 'should fireup the callback', -> 
    countdown_callback = jasmine.createSpy('countdown_callback'); 

    dummy_method(countdown_callback) 
    jasmine.Clock.tick(1001) 
    expect(countdown_callback).toHaveBeenCalled() 

ответ

2

Жасмин просто пытаются вызвать функцию, где тест Sinon если прошло Аргумент - это функция или строка. Если его строка вызывает eval.

Жасмин:

jasmine.getGlobal().setTimeout = function(funcToCall, millis) { 
    if (jasmine.Clock.installed.setTimeout.apply) { 
    return jasmine.Clock.installed.setTimeout.apply(this, arguments); 
    } else { 
    return jasmine.Clock.installed.setTimeout(funcToCall, millis); 
    } 
}; 

Sinon:

if (typeof timer.func == "function") { 
    timer.func.apply(null, timer.invokeArgs); 
} else { 
    eval(timer.func); 
} 

Так что это будет пройти тест Jasmin

setTimeout(fire_callback, 1000); 

в то время как это не получится

setTimeout("fire_callback()", 1000); 
+0

Черт побери! Я даже не знал, что объект функции может быть передан в setTimeout и setInterval ... Плохая привычка, я думаю :( – demental