- Getting Started
- DOM Interactions
- jQuery to the Rescue!
- Stubbing Functions
- Mocking AJAX Requests
- Wrapping Up
Stubbing Functions
Skipping ahead, let's look at what happens when a user clicks the delete button. We know that a confirm dialog box appears. If the user confirms, the li is removed from the page; otherwise, it does nothing.
# spec/javascripts/views/todos/todo_view_spec.coffee describe "clicking the delete button", -> describe "if confirmed", -> it "will remove the todo from the page", -> page.html().should.contain($(@view.el).html()) $(".delete").click() page.html().should.not.contain($(@view.el).html()) describe "if not confirmed", -> it "will not remove the todo from the page", -> page.html().should.contain($(@view.el).html()) $(".delete").click() page.html().should.contain($(@view.el).html())
If we ran this test in the browser, we'd get something similar to Figure 1.
As the figure shows, the confirm pop-up presents itself, and the user has to click OK or Cancel. This isn't going to work in a headless browser, and certainly we can't be expected to have to click the appropriate answer for each test manually. So how do we fix this problem?
Stubs provide the solution. Stubs let us "fake" parts of code, having those bits of code return what we want. In this case, we want to stub out the browser's confirm prompt so that it returns true or false based on what's most appropriate for the test at hand. Enter Sinon.js to solve this issue and others, as we'll see in just a minute.
Simply download Sinon.js and place it into the spec/javascripts/support folder. The spec_helper.coffee file will automatically pick it up and make it available to us.
Now we can easily stub out the confirm function to return true or false depending on our needs, like this:
# spec/javascripts/views/todos/todo_view_spec.coffee describe "clicking the delete button", -> describe "if confirmed", -> beforeEach -> @confirmStub = sinon.stub(window, "confirm") @confirmStub.returns(true) afterEach -> @confirmStub.restore() it "will remove the todo from the page", -> page.html().should.contain($(@view.el).html()) $(".delete").click() page.html().should.not.contain($(@view.el).html())
It's important to call the restore function on the stub after we're finished with it, so that the original functionality of the stubbed function is returned. Otherwise, it could lead to some very unusual issues with other tests further down the line.
With that stub in place, the tests will run through without actually prompting you to confirm.