Протестируйте функцию обратного вызова «Готово» отложенного объекта jQuery с помощью sinon.js

У меня есть этот фрагмент кода CoffeeScript в одном из моих представлений Backbone:

myMethod: ->
     # some code here

     $.when(
          # ...
     ).done(
          @myCallback
     )

и я хочу проверить, что myCallback вызывается в готовом блоке.

Я не уверен, как это сделать в Mocha.js + Sinon.js. Я смог шпионить за jquery и проверить, вызывается ли метод when:

spy = sinon.spy($, 'when')
@view.myMethod()
spy.called.should.be.true
spy.restore()

Но я не могу сделать то же самое с готовым блоком, потому что, если я правильно его понял, он связан с отложенным объектом, возвращаемым методом when.

Я также пробовал что-то вроде этого:

# NOT WORKING CODE
stub = sinon.stub($.Deferred(), 'done').returns
     myCallback: sinon.stub()
@view.myMethod()
stub.called.should.be.true
stub.restore()

но все еще получаю:

expected false to be true

Есть идеи? :)


person lucke84    schedule 23.01.2013    source источник
comment
разве вы не должны использовать @myCallback вместо @myCallback()? Просто слепое предположение. Но $.done не существует. done является частью объекта обещания, поэтому я думаю, что это будет $.Deferred().done   -  person pocesar    schedule 23.01.2013
comment
@pocesar, вы правы, это опечатка (раз я не использовал копирование и вставку .. извините!). Я согласен с вами по поводу отложенного, я написал это так, чтобы было понятно, чего я хотел бы достичь. Я пытался шпионить за этим, а также безуспешно пытался заглушить объект обещания. Дальнейшие идеи?   -  person lucke84    schedule 23.01.2013


Ответы (2)


Вы можете заглушить $.when так же, как и запрос ajax. Во-первых, вы должны заглушить $.when и вернуть объект $.Deferred.

var stub = sinon.stub($, "when", function (event) {
    var result = $.Deferred();
    result.args = event;
    return result;
})

После вызова функции, которую вы хотите протестировать, получите возвращаемое значение конкретного вызова $.when, который будет отложенным объектом. Разрешите это вручную, и вы сможете сделать утверждение о вызываемом @myCallback.

@view.myMethod()

// Get first when call
var call = $.when.getCall(0).returnValue;

// To return successful when call (having used .done() )
call.resolve();
person Maarten Manders    schedule 06.07.2016

Издеваться над ним в классе представления?

#arrange
view = new View
view.myCallback = sinon.spy()

#act
view.myMethod()

#assert
view.myCallback.called.should.be.true

Был ли обратный вызов вызван как отложенный обработчик done или каким-либо другим способом, является деталью реализации. Все, что должно иметь значение, это то, что метод был вызван (с правильными аргументами, если вы выберете).

person jevakallio    schedule 23.01.2013
comment
все еще кажется, что функция не была вызвана. Может быть, обратный вызов done не может быть запущен по каким-то причинам? - person lucke84; 23.01.2013
comment
Может быть, ваш тест нашел ошибку :) Кстати. Я не уверен, что мое утверждение sinon верно, просто скопировано из вашего вопроса. Только когда-либо использовал синон с утверждениями Жасмин. - person jevakallio; 23.01.2013
comment
Если да, то надеюсь это выяснить :) Функция рабочая, написана без тестов, пока я не заметил, и не хочется оставлять ее нераскрытой. Утверждение в порядке, использовалось много раз раньше, на самом деле я получаю хорошую ошибку. - person lucke84; 23.01.2013
comment
Является ли отложенная операция асинхронной? Вам нужно объявить тесты асинхронными с Mocha? - person jevakallio; 23.01.2013
comment
Или, может быть, если deferred является асинхронным, обратный вызов ЕЩЕ не вызывается во время assert. Однако не знаю, как справиться с этим с Mocha. - person jevakallio; 23.01.2013
comment
Может быть, вы правы, и это еще не вызвано, когда я утверждаю свое ожидание. Как бы вы справились с этим (даже с жасмином)? - person lucke84; 24.01.2013
comment
В Jasmine вы бы использовали waitsFor. См. github.com/pivotal/jasmine/wiki/Asynchronous-specs. - person jevakallio; 24.01.2013