In a previous post I discussed how to unit-test client-side AJAX JavaScript code using JsUnit. In that post I dealt with raw XmlHttpRequests. What if you’re using a library such as Prototype, which provides a layer between your JavaScript and the raw request? Let’s look at how you can hook into Prototype’s AJAX functionality in order to mock out the raw request.
In Prototype, there’s an object called Ajax that has a method called getTransport, which returns an XmlHttpRequest. In our test page, we can replace getTransport with a different implementation:
Ajax.getTransport = createMockTransport; var request; function createMockTransport() { request = new MockXmlHttpRequest(); return request; }
That’s basically it: we now have a mock request that looks to Prototype like a real one. There are a couple of gotchas, though.
setRequestHeader
Protoype calls setRequestHeader on the XmlHttpRequest. The latest version of JsUnit’s MockXmlHttpRequest mocks out setRequestHeader, but some earlier versions did not. If you’re using a version earlier than 2.2alpha22, you’ll need to add this method to your mock request:
request.setRequestHeader = function(label, value) { }
(You can hold on to the request headers, of course, if you want to test them.)
abort
If your request ever gets aborted by your code, Prototype may encounter issues. To simulate an abort in your mock request that makes Prototype happy, try adding the following:
request.aborted = false; request.abort = function() { this.aborted = true; this.readyState = 4; this.onreadystatechange(); this.responseIsSuccess = function() { throw new Error("simulating crash when attempting to access request.transport.status"); } }
About the Author