使用Sinon.js并阻止对我的应用服务器的调用

时间:2012-06-11 01:57:12

标签: jquery coffeescript jquery-deferred sinon

简单问题:

我希望我们sinon.js测试一段javascript以确保它在做两件事时调用$.ajax方法:

  1. 我不想实际点击服务器
  2. 我想模拟服务器的响应
  3. 所以这是JS:

      $.ajax
        url: "/tickets/id.json"
        dataType: 'json'
    
      .done (data) =>
        HandlebarsTemplates["tickets/popup_title"] data
    

    这是我的测试:

    describe 'PopupDisplayer', ->
    
      beforeEach ->
        loadFixtures 'popup_displayer'
        new PopupDisplayer
    
        @title_stub = sinon.stub( HandlebarsTemplates, "tickets/popup_title")
    
        @jquery_stub = sinon.stub(jQuery, 'ajax').yieldsTo('done', {})
    
        //This triggers the ajax call
        $('.popupable .title').mouseenter()
    
      afterEach ->
        HandlebarsTemplates['tickets/popup_title'].restore()
        HandlebarsTemplates['tickets/popup_content'].restore()
    
        jQuery.ajax.restore()
    
        @server.restore()
    
      it 'renders the title with the data returned from the server', ->
        expect(@title_stub).toHaveBeenCalledWith( {})  
    

    此测试失败但有以下异常:

    TypeError: ajax expected to yield to 'done', but no object with such a property was passed. Received [[object Object]]
    

    所以我想我想知道我是否可以模拟jQuery请求以获得能够成功响应.done调用的响应,显然我不太了解defferedObject()。< / p>

1 个答案:

答案 0 :(得分:3)

要模拟服务器的响应,您希望存根$.ajax的返回值:

  ...
  @jquery_stub = sinon.stub(jQuery, 'ajax').returns
    done: (callback) -> callback {...} # your object here
  ...

请注意,这只会存储done回调。如果您想测试其他行为,您可能需要实现其他处理程序(failthen等)。

您还可以返回实际的jQuery Deferred对象:

  ...    
  @deferred = new jQuery.Deferred
  @jquery_stub = sinon.stub(jQuery, 'ajax').returns(deferred)
  ...

在这种情况下,您必须在进行测试之前显式触发返回的Deferred:

  ...    
  @deferred.resolveWith(null, [{}]) # your object here
  ...