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:
parent
7900fc3e18
commit
c2a02dbdf6
188
lib/mock-ajax.js
188
lib/mock-ajax.js
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
@ -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";
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
beforeEach(function() {
|
// beforeEach(function() {
|
||||||
clearAjaxRequests();
|
// clearAjaxRequests();
|
||||||
});
|
// });
|
||||||
|
@ -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();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
37
spec/javascripts/with-mock-spec.js
Normal file
37
spec/javascripts/with-mock-spec.js
Normal 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();
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user