We no longer use jQuery and CoffeeScript
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:
<div class="users">...</div>container in the current DOM. Obviously the Jasmine spec runner has no such container.
/usersand we want to prevent network interaction in our unit test.
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'
<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 saying
affix('.users'). jasmine-fixture will append the container to the document body and clean it up after the test.
itblock. We are calling
done()once the response has been received and observed by the test.
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 calling
See Jasmine: Mocking API requests in an Angular service spec on how to do similar things in an Angular application.