Rework jasmine ajax to behave more like the jasmine clock and spys

- use an instance of MockAjax for nicer tests
- the only global install is `mockAjax`
- mockAjax has a `requests` to track requests that have been made
- mockAjax has a `stubs` to track stubs that have been registered
- use just `install` and `uninstall` to be consistent with clock
This commit is contained in:
slackersoft 2013-10-11 22:16:22 -07:00
parent 7900fc3e18
commit c2a02dbdf6
7 changed files with 314 additions and 365 deletions

View File

@ -31,28 +31,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
(function() { (function() {
var jasmineAjaxInterface = {
// Jasmine-Ajax interface
ajaxRequests: [],
ajaxStubs: [],
mostRecentAjaxRequest: function() {
if (ajaxRequests.length > 0) {
return ajaxRequests[ajaxRequests.length - 1];
} else {
return null;
}
},
clearAjaxRequests: function() {
ajaxRequests = [];
},
clearAjaxStubs: function() {
ajaxStubs = [];
}
};
function extend(destination, source) { function extend(destination, source) {
for (var property in source) { for (var property in source) {
destination[property] = source[property]; destination[property] = source[property];
@ -60,20 +38,67 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
return destination; return destination;
} }
if (typeof window === "undefined" && typeof exports === "object") { function MockAjax(global) {
extend(exports, jasmineAjaxInterface); var requestTracker = new RequestTracker(),
} else { stubTracker = new StubTracker(),
extend(window, jasmineAjaxInterface); realAjaxFunction = global.XMLHttpRequest,
} mockAjaxFunction = fakeRequest(requestTracker, stubTracker);
// Fake XHR for mocking Ajax Requests & Responses this.install = function() {
global.XMLHttpRequest = mockAjaxFunction;
window.FakeXMLHttpRequest = function() {
ajaxRequests.push(this);
}; };
extend(window.FakeXMLHttpRequest.prototype, window.XMLHttpRequest); this.uninstall = function() {
extend(window.FakeXMLHttpRequest.prototype, { global.XMLHttpRequest = realAjaxFunction;
};
this.stubRequest = function(url) {
var stub = new RequestStub(url);
stubTracker.addStub(stub);
return stub;
};
this.withMock = function(closure) {
this.install();
try {
closure();
} finally {
this.uninstall();
}
};
this.requests = requestTracker;
this.stubs = stubTracker;
}
function StubTracker() {
var stubs = [];
this.addStub = function(stub) {
stubs.push(stub);
};
this.reset = function() {
stubs = [];
};
this.findStub = function(url) {
for (var i = stubs.length - 1; i >= 0; i--) {
var stub = stubs[i];
if (stub.url === url) {
return stub;
}
}
};
}
function fakeRequest(requestTracker, stubTracker) {
function FakeXMLHttpRequest() {
requestTracker.track(this);
}
extend(FakeXMLHttpRequest.prototype, window.XMLHttpRequest);
extend(FakeXMLHttpRequest.prototype, {
requestHeaders: {}, requestHeaders: {},
open: function() { open: function() {
@ -106,7 +131,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
this.params = data; this.params = data;
this.readyState = 2; this.readyState = 2;
var stub = jasmine.Ajax.matchStub(this.url); var stub = stubTracker.findStub(this.url);
if (stub) { if (stub) {
this.response(stub); this.response(stub);
} }
@ -161,81 +186,48 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
} }
}); });
jasmine.Ajax = { return FakeXMLHttpRequest;
isInstalled: function() {
return jasmine.Ajax.installed === true;
},
assertInstalled: function() {
if (!jasmine.Ajax.isInstalled()) {
throw new Error("Mock ajax is not installed, use jasmine.Ajax.useMock()");
} }
},
useMock: function(closure) { function RequestTracker() {
jasmine.Ajax.installMock(); var requests = [];
try {
closure();
} finally {
jasmine.Ajax.uninstallMock();
}
},
installMock: function() { this.track = function(request) {
jasmine.Ajax.installTopLevel(); requests.push(request);
jasmine.Ajax.installed = true;
},
installTopLevel: function() {
jasmine.Ajax.mode = 'toplevel';
jasmine.Ajax.real = window.XMLHttpRequest;
window.XMLHttpRequest = window.FakeXMLHttpRequest;
},
uninstallMock: function() {
jasmine.Ajax.assertInstalled();
window.XMLHttpRequest = jasmine.Ajax.real;
jasmine.Ajax.reset();
},
reset: function() {
jasmine.Ajax.installed = false;
jasmine.Ajax.mode = null;
jasmine.Ajax.real = null;
},
stubRequest: function(url) {
var Stub = function(url) {
this.url = url;
}; };
Stub.prototype.andReturn = function(options) { this.first = function() {
return requests[0];
};
this.count = function() {
return requests.length;
};
this.reset = function() {
requests = [];
};
this.mostRecent = function() {
return requests[requests.length - 1];
};
}
function RequestStub(url) {
this.url = url;
this.andReturn = function(options) {
this.status = options.status || 200; this.status = options.status || 200;
this.contentType = options.contentType; this.contentType = options.contentType;
this.responseText = options.responseText; this.responseText = options.responseText;
}; };
var stub = new Stub(url);
ajaxStubs.push(stub);
return stub;
},
matchStub: function(url) {
for (var i = ajaxStubs.length - 1; i >= 0; i--) {
var stub = ajaxStubs[i];
if (stub.url === url) {
return stub;
} }
if (typeof window === "undefined" && typeof exports === "object") {
exports.MockAjax = MockAjax;
} else {
window.MockAjax = MockAjax;
} }
},
installed: false,
mode: null
};
}()); }());

View File

@ -1,8 +1,13 @@
describe("FakeXMLHttpRequest", function() { describe("FakeXMLHttpRequest", function() {
var xhr; var xhr;
beforeEach(function() { beforeEach(function() {
xhr = new FakeXMLHttpRequest(); var realXMLHttpRequest = jasmine.createSpy('realRequest'),
fakeGlobal = {XMLHttpRequest: realXMLHttpRequest},
mockAjax = new MockAjax(fakeGlobal);
mockAjax.install();
xhr = new fakeGlobal.XMLHttpRequest();
}); });
it("should have an initial readyState of 0 (uninitialized)", function() { it("should have an initial readyState of 0 (uninitialized)", function() {
expect(xhr.readyState).toEqual(0); expect(xhr.readyState).toEqual(0);
}); });
@ -52,6 +57,7 @@ describe("FakeXMLHttpRequest", function() {
}); });
it("can be extended", function(){ it("can be extended", function(){
pending("why do we want to do this?");
FakeXMLHttpRequest.prototype.foo = function(){ FakeXMLHttpRequest.prototype.foo = function(){
return "foo"; return "foo";
}; };

View File

@ -1,3 +1,3 @@
beforeEach(function() { // beforeEach(function() {
clearAjaxRequests(); // clearAjaxRequests();
}); // });

View File

@ -1,116 +1,52 @@
describe("jasmine.Ajax", function() { describe("mockAjax", function() {
beforeEach(function() { it("does not replace XMLHttpRequest until it is installed", function() {
jasmine.Ajax.reset(); var fakeXmlHttpRequest = jasmine.createSpy('fakeXmlHttpRequest'),
fakeGlobal = { XMLHttpRequest: fakeXmlHttpRequest },
mockAjax = new MockAjax(fakeGlobal);
fakeGlobal.XMLHttpRequest('foo');
expect(fakeXmlHttpRequest).toHaveBeenCalledWith('foo');
fakeXmlHttpRequest.calls.reset();
mockAjax.install();
fakeGlobal.XMLHttpRequest('foo');
expect(fakeXmlHttpRequest).not.toHaveBeenCalled();
}); });
describe("isInstalled", function() { it("replaces the global XMLHttpRequest on uninstall", function() {
it("returns true if the mock has been installed", function() { var fakeXmlHttpRequest = jasmine.createSpy('fakeXmlHttpRequest'),
jasmine.Ajax.installed = true; fakeGlobal = { XMLHttpRequest: fakeXmlHttpRequest },
expect(jasmine.Ajax.isInstalled()).toBeTruthy(); mockAjax = new MockAjax(fakeGlobal);
mockAjax.install();
mockAjax.uninstall();
fakeGlobal.XMLHttpRequest('foo');
expect(fakeXmlHttpRequest).toHaveBeenCalledWith('foo');
}); });
it("returns false if the mock has not been installed", function() { it("allows the httpRequest to be retrieved", function() {
jasmine.Ajax.installed = false; var fakeXmlHttpRequest = jasmine.createSpy('fakeXmlHttpRequest'),
expect(jasmine.Ajax.isInstalled()).toBeFalsy(); fakeGlobal = { XMLHttpRequest: fakeXmlHttpRequest },
}); mockAjax = new MockAjax(fakeGlobal);
mockAjax.install();
var request = new fakeGlobal.XMLHttpRequest();
expect(mockAjax.requests.count()).toBe(1);
expect(mockAjax.requests.mostRecent()).toBe(request);
}); });
describe("assertInstalled", function() { it("allows the httpRequests to be cleared", function() {
it("doesn't raise an error if the mock is installed", function() { var fakeXmlHttpRequest = jasmine.createSpy('fakeXmlHttpRequest'),
jasmine.Ajax.installed = true; fakeGlobal = { XMLHttpRequest: fakeXmlHttpRequest },
expect( mockAjax = new MockAjax(fakeGlobal);
function() {
jasmine.Ajax.assertInstalled();
}).not.toThrowError("Mock ajax is not installed, use jasmine.Ajax.useMock()");
});
it("raises an error if the mock is not installed", function() { mockAjax.install();
jasmine.Ajax.installed = false; var request = new fakeGlobal.XMLHttpRequest();
expect(
function() {
jasmine.Ajax.assertInstalled();
}).toThrowError("Mock ajax is not installed, use jasmine.Ajax.useMock()");
});
});
describe("installMock", function() { expect(mockAjax.requests.mostRecent()).toBe(request);
describe("when using a top-level replacement", function() { mockAjax.requests.reset();
expect(mockAjax.requests.count()).toBe(0);
it("installs the mock", function() {
jasmine.Ajax.installMock();
expect(window.XMLHttpRequest).toBe(FakeXMLHttpRequest);
});
it("saves a reference to the browser's XHR", function() {
var xhr = window.XMLHttpRequest;
jasmine.Ajax.installMock();
expect(jasmine.Ajax.real).toBe(xhr);
});
it("sets mode to 'toplevel'", function() {
jasmine.Ajax.installMock();
expect(jasmine.Ajax.mode).toEqual("toplevel");
}); });
}); });
it("sets the installed flag to true", function() {
jasmine.Ajax.installMock();
expect(jasmine.Ajax.installed).toBeTruthy();
});
});
describe("uninstallMock", function() {
describe("when using toplevel", function() {
it("returns ajax control to the browser object", function() {
var xhr = window.XMLHttpRequest;
jasmine.Ajax.installMock();
jasmine.Ajax.uninstallMock();
expect(window.XMLHttpRequest).toBe(xhr);
});
});
it("raises an exception if jasmine.Ajax is not installed", function() {
expect(function(){ jasmine.Ajax.uninstallMock(); }).toThrowError("Mock ajax is not installed, use jasmine.Ajax.useMock()");
});
it("sets the installed flag to false", function() {
jasmine.Ajax.installMock();
jasmine.Ajax.uninstallMock();
expect(jasmine.Ajax.installed).toBeFalsy();
// so uninstallMock doesn't throw error when spec.after runs
jasmine.Ajax.installMock();
});
it("sets the mode to null", function() {
jasmine.Ajax.installMock();
jasmine.Ajax.uninstallMock();
expect(jasmine.Ajax.mode).toEqual(null);
jasmine.Ajax.installMock();
});
});
describe("useMock", function() {
it("installs the mock and uninstalls when done", function() {
var realRequest = spyOn(window, 'XMLHttpRequest'),
fakeRequest = spyOn(window, 'FakeXMLHttpRequest');
expect(function() {
jasmine.Ajax.useMock(function() {
window.XMLHttpRequest();
throw "function that has an error"
});
}).toThrow();
expect(realRequest).not.toHaveBeenCalled();
expect(fakeRequest).toHaveBeenCalled();
fakeRequest.calls.reset();
window.XMLHttpRequest();
expect(realRequest).toHaveBeenCalled();
expect(fakeRequest).not.toHaveBeenCalled();
});
});
});

View File

@ -3,9 +3,13 @@ describe("Jasmine Mock Ajax (for toplevel)", function() {
var success, error, complete; var success, error, complete;
var client, onreadystatechange; var client, onreadystatechange;
var sharedContext = {}; var sharedContext = {};
var fakeGlobal, mockAjax;
beforeEach(function() { beforeEach(function() {
jasmine.Ajax.installMock(); var fakeXMLHttpRequest = jasmine.createSpy('realFakeXMLHttpRequest');
fakeGlobal = {XMLHttpRequest: fakeXMLHttpRequest};
mockAjax = new MockAjax(fakeGlobal);
mockAjax.install();
success = jasmine.createSpy("onSuccess"); success = jasmine.createSpy("onSuccess");
error = jasmine.createSpy("onFailure"); error = jasmine.createSpy("onFailure");
@ -29,17 +33,13 @@ describe("Jasmine Mock Ajax (for toplevel)", function() {
}; };
}); });
afterEach(function() {
jasmine.Ajax.uninstallMock();
});
describe("when making a request", function () { describe("when making a request", function () {
beforeEach(function() { beforeEach(function() {
client = new XMLHttpRequest(); client = new fakeGlobal.XMLHttpRequest();
client.onreadystatechange = onreadystatechange; client.onreadystatechange = onreadystatechange;
client.open("GET", "example.com/someApi"); client.open("GET", "example.com/someApi");
client.send(); client.send();
request = mostRecentAjaxRequest(); request = mockAjax.requests.mostRecent();
}); });
it("should store URL and transport", function() { it("should store URL and transport", function() {
@ -47,73 +47,74 @@ describe("Jasmine Mock Ajax (for toplevel)", function() {
}); });
it("should queue the request", function() { it("should queue the request", function() {
expect(ajaxRequests.length).toEqual(1); expect(mockAjax.requests.count()).toEqual(1);
}); });
it("should allow access to the queued request", function() { it("should allow access to the queued request", function() {
expect(ajaxRequests[0]).toEqual(request); expect(mockAjax.requests.first()).toEqual(request);
}); });
describe("and then another request", function () { describe("and then another request", function () {
beforeEach(function() { beforeEach(function() {
client = new XMLHttpRequest(); client = new fakeGlobal.XMLHttpRequest();
client.onreadystatechange = onreadystatechange; client.onreadystatechange = onreadystatechange;
client.open("GET", "example.com/someApi"); client.open("GET", "example.com/someApi");
client.send(); client.send();
anotherRequest = mostRecentAjaxRequest(); anotherRequest = mockAjax.requests.mostRecent();
}); });
it("should queue the next request", function() { it("should queue the next request", function() {
expect(ajaxRequests.length).toEqual(2); expect(mockAjax.requests.count()).toEqual(2);
}); });
it("should allow access to the other queued request", function() { it("should allow access to the other queued request", function() {
expect(ajaxRequests[1]).toEqual(anotherRequest); expect(mockAjax.requests.first()).toEqual(request);
expect(mockAjax.requests.mostRecent()).toEqual(anotherRequest);
}); });
}); });
describe("mostRecentAjaxRequest", function () { describe("mockAjax.requests.mostRecent()", function () {
describe("when there is one request queued", function () { describe("when there is one request queued", function () {
it("should return the request", function() { it("should return the request", function() {
expect(mostRecentAjaxRequest()).toEqual(request); expect(mockAjax.requests.mostRecent()).toEqual(request);
}); });
}); });
describe("when there is more than one request", function () { describe("when there is more than one request", function () {
beforeEach(function() { beforeEach(function() {
client = new XMLHttpRequest(); client = new fakeGlobal.XMLHttpRequest();
client.onreadystatechange = onreadystatechange; client.onreadystatechange = onreadystatechange;
client.open("GET", "example.com/someApi"); client.open("GET", "example.com/someApi");
client.send(); client.send();
anotherRequest = mostRecentAjaxRequest(); anotherRequest = mockAjax.requests.mostRecent();
}); });
it("should return the most recent request", function() { it("should return the most recent request", function() {
expect(mostRecentAjaxRequest()).toEqual(anotherRequest); expect(mockAjax.requests.mostRecent()).toEqual(anotherRequest);
}); });
}); });
describe("when there are no requests", function () { describe("when there are no requests", function () {
beforeEach(function() { beforeEach(function() {
clearAjaxRequests(); mockAjax.requests.reset();
}); });
it("should return null", function() { it("should return null", function() {
expect(mostRecentAjaxRequest()).toEqual(null); expect(mockAjax.requests.mostRecent()).toBeUndefined();
}); });
}); });
}); });
describe("clearAjaxRequests()", function () { describe("clearAjaxRequests()", function () {
beforeEach(function() { beforeEach(function() {
clearAjaxRequests(); mockAjax.requests.reset();
}); });
it("should remove all requests", function() { it("should remove all requests", function() {
expect(ajaxRequests.length).toEqual(0); expect(mockAjax.requests.count()).toEqual(0);
expect(mostRecentAjaxRequest()).toEqual(null); expect(mockAjax.requests.mostRecent()).toBeUndefined();
}); });
}); });
}); });
@ -121,13 +122,13 @@ describe("Jasmine Mock Ajax (for toplevel)", function() {
describe("when simulating a response with request.response", function () { describe("when simulating a response with request.response", function () {
describe("and the response is Success", function () { describe("and the response is Success", function () {
beforeEach(function() { beforeEach(function() {
client = new XMLHttpRequest(); client = new fakeGlobal.XMLHttpRequest();
client.onreadystatechange = onreadystatechange; client.onreadystatechange = onreadystatechange;
client.open("GET", "example.com/someApi"); client.open("GET", "example.com/someApi");
client.setRequestHeader("Content-Type", "text/plain") client.setRequestHeader("Content-Type", "text/plain")
client.send(); client.send();
request = mostRecentAjaxRequest(); request = mockAjax.requests.mostRecent();
response = {status: 200, contentType: "text/html", responseText: "OK!"}; response = {status: 200, contentType: "text/html", responseText: "OK!"};
request.response(response); request.response(response);
@ -154,13 +155,13 @@ describe("Jasmine Mock Ajax (for toplevel)", function() {
describe("and the response is Success, but with JSON", function () { describe("and the response is Success, but with JSON", function () {
beforeEach(function() { beforeEach(function() {
client = new XMLHttpRequest(); client = new fakeGlobal.XMLHttpRequest();
client.onreadystatechange = onreadystatechange; client.onreadystatechange = onreadystatechange;
client.open("GET", "example.com/someApi"); client.open("GET", "example.com/someApi");
client.setRequestHeader("Content-Type", "application/json") client.setRequestHeader("Content-Type", "application/json")
client.send(); client.send();
request = mostRecentAjaxRequest(); request = mockAjax.requests.mostRecent();
var responseObject = {status: 200, contentType: "application/json", responseText: '{"foo":"bar"}'}; var responseObject = {status: 200, contentType: "application/json", responseText: '{"foo":"bar"}'};
request.response(responseObject); request.response(responseObject);
@ -194,13 +195,13 @@ describe("Jasmine Mock Ajax (for toplevel)", function() {
describe("the content type defaults to application/json", function () { describe("the content type defaults to application/json", function () {
beforeEach(function() { beforeEach(function() {
client = new XMLHttpRequest(); client = new fakeGlobal.XMLHttpRequest();
client.onreadystatechange = onreadystatechange; client.onreadystatechange = onreadystatechange;
client.open("GET", "example.com/someApi"); client.open("GET", "example.com/someApi");
client.setRequestHeader("Content-Type", "application/json") client.setRequestHeader("Content-Type", "application/json")
client.send(); client.send();
request = mostRecentAjaxRequest(); request = mockAjax.requests.mostRecent();
response = {status: 200, responseText: '{"foo": "valid JSON, dammit."}'}; response = {status: 200, responseText: '{"foo": "valid JSON, dammit."}'};
request.response(response); request.response(response);
@ -227,13 +228,13 @@ describe("Jasmine Mock Ajax (for toplevel)", function() {
describe("and the status/response code is 0", function () { describe("and the status/response code is 0", function () {
beforeEach(function() { beforeEach(function() {
client = new XMLHttpRequest(); client = new fakeGlobal.XMLHttpRequest();
client.onreadystatechange = onreadystatechange; client.onreadystatechange = onreadystatechange;
client.open("GET", "example.com/someApi"); client.open("GET", "example.com/someApi");
client.setRequestHeader("Content-Type", "text/plain") client.setRequestHeader("Content-Type", "text/plain")
client.send(); client.send();
request = mostRecentAjaxRequest(); request = mockAjax.requests.mostRecent();
response = {status: 0, responseText: '{"foo": "whoops!"}'}; response = {status: 0, responseText: '{"foo": "whoops!"}'};
request.response(response); request.response(response);
@ -261,13 +262,13 @@ describe("Jasmine Mock Ajax (for toplevel)", function() {
describe("and the response is error", function () { describe("and the response is error", function () {
beforeEach(function() { beforeEach(function() {
client = new XMLHttpRequest(); client = new fakeGlobal.XMLHttpRequest();
client.onreadystatechange = onreadystatechange; client.onreadystatechange = onreadystatechange;
client.open("GET", "example.com/someApi"); client.open("GET", "example.com/someApi");
client.setRequestHeader("Content-Type", "text/plain") client.setRequestHeader("Content-Type", "text/plain")
client.send(); client.send();
request = mostRecentAjaxRequest(); request = mockAjax.requests.mostRecent();
response = {status: 500, contentType: "text/html", responseText: "(._){"}; response = {status: 500, contentType: "text/html", responseText: "(._){"};
request.response(response); request.response(response);
@ -296,13 +297,13 @@ describe("Jasmine Mock Ajax (for toplevel)", function() {
beforeEach(function() { beforeEach(function() {
clock.install(); clock.install();
client = new XMLHttpRequest(); client = new fakeGlobal.XMLHttpRequest();
client.onreadystatechange = onreadystatechange; client.onreadystatechange = onreadystatechange;
client.open("GET", "example.com/someApi"); client.open("GET", "example.com/someApi");
client.setRequestHeader("Content-Type", "text/plain") client.setRequestHeader("Content-Type", "text/plain")
client.send(); client.send();
request = mostRecentAjaxRequest(); request = mockAjax.requests.mostRecent();
response = {contentType: "text/html", responseText: "(._){"}; response = {contentType: "text/html", responseText: "(._){"};
request.responseTimeout(response); request.responseTimeout(response);

View File

@ -1,11 +1,12 @@
describe("Webmock style mocking", function() { describe("Webmock style mocking", function() {
var successSpy, errorSpy, response; var successSpy, errorSpy, response, fakeGlobal, mockAjax;
var sendRequest = function() { var sendRequest = function(fakeGlobal) {
var xhr = new XMLHttpRequest(); var xhr = new fakeGlobal.XMLHttpRequest();
xhr.onreadystatechange = function(arguments) { xhr.onreadystatechange = function(arguments) {
if (this.readyState == this.DONE) { if (this.readyState == this.DONE) {
response = this; response = this;
successSpy();
} }
}; };
@ -14,47 +15,44 @@ describe("Webmock style mocking", function() {
}; };
beforeEach(function() { beforeEach(function() {
jasmine.Ajax.installMock(); successSpy = jasmine.createSpy('success');
jasmine.Ajax.stubRequest("http://example.com/someApi").andReturn({responseText: "hi!"}); fakeGlobal = {XMLHttpRequest: jasmine.createSpy('realXMLHttpRequest')};
mockAjax = new MockAjax(fakeGlobal);
mockAjax.install();
sendRequest(); mockAjax.stubRequest("http://example.com/someApi").andReturn({responseText: "hi!"});
}); });
afterEach(function() { it("allows a url to be setup as a stub", function() {
jasmine.Ajax.uninstallMock(); sendRequest(fakeGlobal);
clearAjaxStubs(); expect(successSpy).toHaveBeenCalled();
}); });
it("should allow you to clear all the ajax stubs", function() { it("should allow you to clear all the ajax stubs", function() {
expect(ajaxStubs.length).toEqual(1); mockAjax.stubs.reset();
clearAjaxStubs(); sendRequest(fakeGlobal);
expect(ajaxStubs.length).toEqual(0); expect(successSpy).not.toHaveBeenCalled();
});
it("should push the new stub on the ajaxStubs", function() {
expect(ajaxStubs.length).toEqual(1);
});
it("should set the url in the stub", function() {
expect(ajaxStubs[0].url).toEqual("http://example.com/someApi");
}); });
it("should set the contentType", function() { it("should set the contentType", function() {
sendRequest(fakeGlobal);
expect(response.responseHeaders['Content-type']).toEqual('application/json'); expect(response.responseHeaders['Content-type']).toEqual('application/json');
}); });
it("should set the responseText", function() { it("should set the responseText", function() {
sendRequest(fakeGlobal);
expect(response.responseText).toEqual('hi!'); expect(response.responseText).toEqual('hi!');
}); });
it("should default the status to 200", function() { it("should default the status to 200", function() {
sendRequest(fakeGlobal);
expect(response.status).toEqual(200); expect(response.status).toEqual(200);
}); });
describe("with another stub for the same url", function() { describe("with another stub for the same url", function() {
beforeEach(function() { beforeEach(function() {
jasmine.Ajax.stubRequest("http://example.com/someApi").andReturn({responseText: "no", status: 403}); mockAjax.stubRequest("http://example.com/someApi").andReturn({responseText: "no", status: 403});
sendRequest(); sendRequest(fakeGlobal);
}); });
it("should set the status", function() { it("should set the status", function() {
@ -65,25 +63,4 @@ describe("Webmock style mocking", function() {
expect(response.responseText).toEqual('no'); expect(response.responseText).toEqual('no');
}); });
}); });
describe(".matchStub", function() {
it("should be able to find a stub with an exact match", function() {
var stub = jasmine.Ajax.matchStub("http://example.com/someApi");
expect(stub).toBeDefined();
});
describe("with another stub for the same url", function() {
beforeEach(function() {
jasmine.Ajax.stubRequest("http://example.com/someApi").andReturn({responseText: "no", status: 403});
});
it("should use the latest stub", function() {
var stub = jasmine.Ajax.matchStub("http://example.com/someApi");
expect(stub.status).toEqual(403);
expect(stub.responseText).toEqual('no');
});
});
});
}); });

View File

@ -0,0 +1,37 @@
describe("withMock", function() {
var sendRequest = function(fakeGlobal) {
var xhr = new fakeGlobal.XMLHttpRequest();
xhr.open("GET", "http://example.com/someApi");
xhr.send();
};
it("installs the mock for passed in function, and uninstalls when complete", function() {
var xmlHttpRequest = spyOn(window, 'XMLHttpRequest').and.returnValue({open: function() {}, send: function() {}}),
fakeGlobal = {XMLHttpRequest: xmlHttpRequest},
mockAjax = new MockAjax(fakeGlobal);
mockAjax.withMock(function() {
sendRequest(fakeGlobal);
expect(xmlHttpRequest).not.toHaveBeenCalled();
});
sendRequest(fakeGlobal);
expect(xmlHttpRequest).toHaveBeenCalled();
});
it("properly uninstalls when the passed in function throws", function() {
var xmlHttpRequest = spyOn(window, 'XMLHttpRequest').and.returnValue({open: function() {}, send: function() {}}),
fakeGlobal = {XMLHttpRequest: xmlHttpRequest},
mockAjax = new MockAjax(fakeGlobal);
expect(function() {
mockAjax.withMock(function() {
throw "error"
});
}).toThrow("error");
sendRequest(fakeGlobal);
expect(xmlHttpRequest).toHaveBeenCalled();
});
});