We no longer use jQuery and CoffeeScript
Here is a Javascript function reloadUsers()
that fetches a HTML snippet from the server using AJAX and replaces the current .users
container in the DOM:
window.reloadUsers = ->
$.get('/users').then (html) ->
$('.users').html(html)
Testing this simple function poses a number of challenges:
- It only works if there is a
<div class="users">...</div>
container in the current DOM. Obviously the Jasmine spec runner has no such container. - The code requests
/users
and we want to prevent network interaction in our unit test. - The AJAX call is asynchronously and we don't have control over when it returns (and hence when it calls the callback function).
Here is a test that does all that:
describe 'reloadUsers', ->
it 'replaces the user list with a fresh copy from /users', (done) ->
# Mock network connections
jasmine.Ajax.install()
# Create the DOM elements the code works on
affix('.users').text('old is')
reloadUsers().then ->
# Observe the result of the function
expect('.users').toHaveText('new users')
# Tell Jasmine that the example is over
done()
# Fetch the last AJAX request for inspection
request = jasmine.Ajax.requests.mostRecent()
expect(request.url).toMatch(/\/users$/)
expect(request.method).toBe('GET')
# Fake the response
request.respondWith
status: 200
contentType: 'text/html'
responseText: 'new users'
Some notes:
- We need a
<div class="users">...</div>
containers for the code to work on. We're using jasmine-fixture Show archive.org snapshot to quickly create such a container from a CSS selector by sayingaffix('.users')
. jasmine-fixture will append the container to the document body and clean it up after the test. - We need to tell Jasmine to wait until the AJAX response was processed. We do this by accepting an argument
done
from theit
block. We are callingdone()
once the response has been received and observed by the test. - We're using
jasmine-ajax
Show archive.org snapshot
to mock access to the network.
jasmine.Ajax.requests.mostRecent()
returns the most recent AJAX request, which we can inspect for its parameters and payload. We can also trigger a fake response by callingrequest.respondWith(...)
. - We're using
jasmine-jquery
Show archive.org snapshot
to get some DOM-related matchers like
haveText(...)
.
See Jasmine: Mocking API requests in an Angular service spec on how to do similar things in an Angular application.
Posted by Henning Koch to makandra dev (2015-01-17 18:42)