aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVojta Jina2012-01-11 11:15:00 -0800
committerVojta Jina2012-01-11 22:11:01 -0800
commit28114de8dcf86c69f533b924ce205533bc265786 (patch)
treee4b76616205ea0f377f57123521076635506a403
parentc6ea1be0536b9d4564f028554fd1762feba58994 (diff)
downloadangular.js-28114de8dcf86c69f533b924ce205533bc265786.tar.bz2
refactor(mock.$httpBackend): split (e2e/unit testing version of $httpBackend mock)
-rw-r--r--src/angular-mocks.js90
-rw-r--r--test/angular-mocksSpec.js86
2 files changed, 108 insertions, 68 deletions
diff --git a/src/angular-mocks.js b/src/angular-mocks.js
index 9cc0db43..25d7c7e7 100644
--- a/src/angular-mocks.js
+++ b/src/angular-mocks.js
@@ -3,6 +3,8 @@
* @license AngularJS v"NG_VERSION_FULL"
* (c) 2010-2011 AngularJS http://angularjs.org
* License: MIT
+ *
+ * TODO(vojta): wrap whole file into closure during build
*/
/**
@@ -578,16 +580,34 @@ angular.mock.dump = function(object){
* @ngdoc object
* @name angular.module.ngMock.$httpBackend
* @describe
- * Fake HTTP backend used by the $http service during testing. This implementation can be used to
- * respond with static or dynamic responses via the `expect` and `when` apis and their shortcuts
- * (`expectGET`, `whenPOST`, etc).
+ * Fake version of `$httpBackend` service used by the `$http` service during unit testing.
+ *
+ * This implementation can be used to respond with static or dynamic responses via the `expect` and
+ * `when` apis and their shortcuts (`expectGET`, `whenPOST`, etc).
*/
-angular.mock.$httpBackendDecorator = function($delegate, $defer) {
+angular.mock.$HttpBackendProvider = function() {
+ this.$get = [createHttpBackendMock];
+};
+
+/**
+ * General factory function for $httpBackend mock.
+ * Returns instance for unit testing (when no arguments specified):
+ * - passing through is disabled
+ * - auto flushing is disabled
+ *
+ * Returns instance for e2e testing (when `$delegate` and `$defer` specified):
+ * - passing through (delegating request to real backend) is enabled
+ * - auto flushing is enabled
+ *
+ * @param {Object=} $delegate Real $httpBackend instance (allow passing through if specified)
+ * @param {Object=} $defer Auto-flushing enabled if specified
+ * @return {Object} Instance of $httpBackend mock
+ */
+function createHttpBackendMock($delegate, $defer) {
var definitions = [],
expectations = [],
responses = [],
- responsesPush = angular.bind(responses, responses.push),
- autoflush = false;
+ responsesPush = angular.bind(responses, responses.push);
function createResponse(status, data, headers) {
if (angular.isFunction(status)) return status;
@@ -638,7 +658,8 @@ angular.mock.$httpBackendDecorator = function($delegate, $defer) {
while ((definition = definitions[++i])) {
if (definition.match(method, url, data, headers || {})) {
if (definition.response) {
- (autoflush ? $defer : responsesPush)(function() {
+ // if $defer specified, we do auto flush all requests
+ ($defer ? $defer : responsesPush)(function() {
var response = definition.response(method, url, data, headers);
xhr.$$respHeaders = response[2];
callback(response[0], response[1], xhr.getAllResponseHeaders());
@@ -656,17 +677,21 @@ angular.mock.$httpBackendDecorator = function($delegate, $defer) {
}
$httpBackend.when = function(method, url, data, headers) {
- var definition = new MockHttpExpectation(method, url, data, headers);
- definitions.push(definition);
- return {
- respond: function(status, data, headers) {
- definition.response = createResponse(status, data, headers);
- },
-
- passThrough: function() {
+ var definition = new MockHttpExpectation(method, url, data, headers),
+ chain = {
+ respond: function(status, data, headers) {
+ definition.response = createResponse(status, data, headers);
+ }
+ };
+
+ if ($defer) {
+ chain.passThrough = function() {
definition.passThrough = true;
- }
- };
+ };
+ }
+
+ definitions.push(definition);
+ return chain;
};
createShortMethods('when');
@@ -701,15 +726,6 @@ angular.mock.$httpBackendDecorator = function($delegate, $defer) {
$httpBackend.verifyNoOutstandingExpectation();
};
-
- $httpBackend.autoflush = function(val) {
- if (arguments.length) {
- autoflush = !!val;
- } else {
- return autoflush;
- }
- }
-
$httpBackend.verifyNoOutstandingExpectation = function() {
if (expectations.length) {
throw Error('Unsatisfied requests: ' + expectations.join(', '));
@@ -836,11 +852,27 @@ function MockXhr() {
angular.module('ngMock', ['ng']).service({
'$browser': angular.mock.$BrowserProvider,
'$exceptionHandler': angular.mock.$ExceptionHandlerProvider,
- '$log': angular.mock.$logProvider
-}).init(function($provide) {
- $provide.decorator('$httpBackend', angular.mock.$httpBackendDecorator);
+ '$log': angular.mock.$logProvider,
+ '$httpBackend': angular.mock.$HttpBackendProvider
+});
+
+
+
+/**
+ * @ngdoc overview
+ * @name angular.module.ngMockE2E
+ * @description
+ *
+ * The `ngMockE2E` is an angular module which contains mock for `$httpBackend`. This mock allows you
+ * to either respond with fake data or delegate to real backend.
+ */
+angular.module('ngMockE2E', ['ng']).init(function($provide) {
+ $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
});
+angular.mock.e2e = {};
+angular.mock.e2e.$httpBackendDecorator = ['$delegate', '$defer', createHttpBackendMock];
+
window.jstestdriver && (function(window){
diff --git a/test/angular-mocksSpec.js b/test/angular-mocksSpec.js
index 248bb108..fbdd3b91 100644
--- a/test/angular-mocksSpec.js
+++ b/test/angular-mocksSpec.js
@@ -1,6 +1,6 @@
'use strict';
-describe('mocks', function() {
+describe('ngMock', function() {
describe('$browser', function() {
@@ -373,19 +373,12 @@ describe('mocks', function() {
describe('$httpBackend', function() {
- var hb, callback, realBackendSpy;
-
- beforeEach(inject(
- function($provide) {
- realBackendSpy = jasmine.createSpy('realBackend');
- $provide.value('$httpBackend', realBackendSpy);
- $provide.decorator('$httpBackend', angular.mock.$httpBackendDecorator)
- },
- function($httpBackend) {
- callback = jasmine.createSpy('callback');
- hb = $httpBackend;
- }
- ));
+ var hb, callback;
+
+ beforeEach(inject(function($httpBackend) {
+ callback = jasmine.createSpy('callback');
+ hb = $httpBackend;
+ }));
it('should respond with first matched definition', function() {
@@ -681,31 +674,8 @@ describe('mocks', function() {
});
- describe('definitions with passThrough delegation', function() {
- it('should delegate requests to the real backend when passThrough is invoked', function() {
- hb.when('GET', /\/passThrough\/.*/).passThrough();
-
- expect(hb('GET', '/passThrough/23', null, callback));
- expect(realBackendSpy).
- toHaveBeenCalledOnceWith('GET', '/passThrough/23', null, callback, undefined);
- });
- });
-
-
- describe('autoflush', function() {
- it('should flush responses via $defer when autoflush is turned on', inject(
- function($browser) {
- expect(hb.autoflush()).toBe(false);
- hb.autoflush(true);
- expect(hb.autoflush()).toBe(true);
-
- hb.when('GET', '/foo').respond('bar');
- hb('GET', '/foo', null, callback);
-
- expect(callback).not.toHaveBeenCalled();
- $browser.defer.flush();
- expect(callback).toHaveBeenCalledOnce();
- }));
+ it('should not have passThrough method', function() {
+ expect(hb.passThrough).toBeUndefined();
});
@@ -856,3 +826,41 @@ describe('mocks', function() {
});
});
});
+
+
+describe('ngMockE2E', function() {
+ describe('$httpBackend', function() {
+ var hb, realHttpBackend, callback;
+
+ beforeEach(inject(function($provide, $injector) {
+ callback = jasmine.createSpy('callback');
+ realHttpBackend = jasmine.createSpy('real $httpBackend');
+ $provide.value('$httpBackend', realHttpBackend);
+ $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
+ hb = $injector.get('$httpBackend');
+ }));
+
+
+ describe('passThrough()', function() {
+ it('should delegate requests to the real backend when passThrough is invoked', function() {
+ hb.when('GET', /\/passThrough\/.*/).passThrough();
+ hb('GET', '/passThrough/23', null, callback);
+
+ expect(realHttpBackend).
+ toHaveBeenCalledOnceWith('GET', '/passThrough/23', null, callback, undefined);
+ });
+ });
+
+
+ describe('autoflush', function() {
+ it('should flush responses via $defer', inject(function($browser) {
+ hb.when('GET', '/foo').respond('bar');
+ hb('GET', '/foo', null, callback);
+
+ expect(callback).not.toHaveBeenCalled();
+ $browser.defer.flush();
+ expect(callback).toHaveBeenCalledOnce();
+ }));
+ });
+ });
+});