Mocking AJAX Requests
When our sample todo application is first loaded, we need to get a list of existing todos from the server and display them to the page. We've already discussed how we display those individual todos, but how do we get that list of todos from the server in our tests? Do we want to connect to a running server and interact with it over actual AJAX requests? Of course not; that would be both problematic and slow. Instead, we'll use Sinon.js again, this time to stub out AJAX requests and responses.
The OMG.Views.TodosListView class works in a simple way. When it's initialized, we give it an empty collection (Backbone.Collection) and tell it to render all of its todos when it receives a reset event. The reset event is triggered when you call the fetch function on the collection. The fetch function makes an AJAX call back to the server to get the list of todos. That's the part we need to make work.
First, let's see how the tests for this should look:
These tests are pretty straightforward. We're asserting that we get two todos back from the server and they're printed to the screen. Figure 2 shows what happens when we try to run these tests.
The answer should be obvious immediately: The @collection object isn't receiving a response from the server when the fetch function is called, because we don't have a running server to respond to it.
In the mock_responses.coffee file, we create a new instance of this fake server (if one doesn't already exist). We then tell it this: If it receives a GET request for the URL /todos, return with a response code of 200, some headers, and a string containing a JSON array that represents two todos.
If we ran the specs again right now, they still would fail, because we haven't told Sinon.js to respond to the request. We've indicated what we want the given response to be, but it gives that response only when asked. There are lot of technical reasons why it doesn't respond automatically, but those are outside the scope of this article.
How and when do we tell Sinon.js to respond to the request? We do that after the AJAX call has been made in the test. We can update the beforeEach to look like this:
Notice that we've added the line MockServer.respond() at the end of the beforeEach block. That will tell Sinon.js to respond to the fetch call that was made in the initializer function in the OMG.Views.TodosListView class.
The tests should now pass. Congratulations!