If you want real end-to-end testing of a page with functioning AJAX, use Selenium. But I was interested in doing just a bit of JS speccing to make sure that the AJAX routes I called worked and that the data that came back fit the JS that I had written.
So, I figured with a little capybara and a little therubyracer, I could test my javascript with real route calls. Let's check it out.
The Javascript I want to test:
var dataObject = {};
var getRemoteData = function() {
$.getJSON('/remote_path.json', function(data) {
dataObject = $.parseJSON(data);
});
}
We will pretend that hitting /remote_path.json returns the following response in JSON:
{ "my_information": "my response data" }
I want to test:
- That /remote_path.json is accessible and returns information
- That dataObject is populated with a Javascript Object containing the params I pass down
Here is my commented testing code:
test 'get some information via ajax' do
# Create a new JS Context. :with => self means that
# the global namespace is the current context
js = V8::Context.new(:with => self)
# Load up our JS file
js.load(File.join(Rails.root, 'public', 'javascripts', 'application.js'))
# Define a mock method for getting JSON data
def getJSON(url, callback)
# When the JS wants some data, get it for real w/ capybara
visit url
# And call the JS function passed in (ruby => js)
callback.call(page.body)
end
js.eval %{
/* Mock out jQuery */
var $ = {};
/* Setup the mock in the right place (JS => ruby) */
$.getJSON = getJSON;
/* Mock out jquery parseJSON to call ruby JSON.parse
Since the args are the same, it is plug and play!
(JS => ruby) */
$.parseJSON = JSON.parse;
/* Trigger our JS */
getRemoteData();
/* Assert what we expect (JS => ruby) */
assert_equal(" ", dataObject.access_key);
}
end
This is not an example of an incredibly useful test, but I found the ability to bind back and forth easily between ruby and javascript to be mind-blowingly incredible. I mean, look at that last line, where I call assert and pass a javascript object to it!
Huge thanks to Charles Lowell (cowboyd) for his hard work on therubyracer.
Enjoy the weekend!
Check out our other articles discussing Capybara: