Using Sinon.js and preventing a call to my app server

coffeescript, jquery, jquery-deferred, sinon

Solution

To mock the server's response you want to stub the return value of `$.ajax`:

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

Note that this only stubs the `done` callback. If you want to test other behaviours you will probably need to implement other handlers (`fail`, `then` etc.).

You could also return an actual jQuery Deferred object:

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

In this case you will have to explicitly trigger the returned Deferred before doing your tests:

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

Problem

Simple enough question: I want us sinon.js to test a piece of javascript to ensure that it calls the `$.ajax` method while doing two things: - I don't want to actually hit the server - I want to mock up a response from the server so here's the JS: ``` $.ajax url: "/tickets/id.json" dataType: 'json' .done (data) => HandlebarsTemplates["tickets/popup_title"] data ``` and here's my test: ``` 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( {}) ``` This test failed though with the following exception: ``` TypeError: ajax expected to yield to 'done', but no object with such a property was passed. Received [[object Object]] ``` So I guess I'm wondering if I can mock up an jQuery request to get a response that can successfully respond to the `.done` call apparently I don't understand the `defferedObject()` well enough.

Original source