1

假设我有以下骨干路由​​器:

class App.Routers.ThingsRouter extends Backbone.Router
  initialize: -> new App.Collections.ThingsCollection()

  index: ->
    that = this
    @collection.fetch success: ->
      view = new App.Views.ThingsIndex(collection: that.collection)
      $('#app-container').html(view.render().el)

我需要编写一个 Jasmine 间谍来监视它并确保它App.Views.ThingsIndex()被调用。但是,由于它是 AJAX,因此以下内容不起作用:

describe 'index', ->
  @router = new App.Routers.ThingsRouter()
  spyOn(@router.collection, 'fetch')
  fake = { render: -> '' }
  @previewsIndexStub = spyOn(Periscope.Views, 'PreviewsIndex').andReturn(fake)
  @router.index()
  expect(@previewsIndexStub).toHaveBeenCalled()

因为 Jasmine 在 AJAX 调用完成之前运行了期望函数。有没有像这样测试回调的好方法?

4

1 回答 1

1

使用 jasmines 内置的 waitsFor & 运行方法,以便在执行期望函数之前等待 ajax 调用完成。有关这两个函数的文档,请参阅Jasmine - 异步规范

describe 'index', ->
  @router = new App.Routers.ThingsRouter()
  spyOn(@router.collection, 'fetch')
  fake = {}; fake.render = -> '';
  @previewsIndexStub = spyOn(Periscope.Views, 'PreviewsIndex').andReturn(fake)
  @router.index()
  waitsFor => @previewsIndexStub.wasCalled
  ###
  Or if you want to wait for the method to be called more than once
  use form waitsFor => @previewsIndexStub.callCount > 1
  ###
  runs => expect(@previewsIndexStub).toHaveBeenCalled()
于 2012-04-05T19:36:06.893 回答