mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-24 13:53:43 +00:00
refactor(mock.$httpBackend): split (e2e/unit testing version of $httpBackend mock)
This commit is contained in:
parent
c6ea1be053
commit
28114de8dc
2 changed files with 106 additions and 66 deletions
88
src/angular-mocks.js
vendored
88
src/angular-mocks.js
vendored
|
|
@ -3,6 +3,8 @@
|
||||||
* @license AngularJS v"NG_VERSION_FULL"
|
* @license AngularJS v"NG_VERSION_FULL"
|
||||||
* (c) 2010-2011 AngularJS http://angularjs.org
|
* (c) 2010-2011 AngularJS http://angularjs.org
|
||||||
* License: MIT
|
* License: MIT
|
||||||
|
*
|
||||||
|
* TODO(vojta): wrap whole file into closure during build
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -578,16 +580,34 @@ angular.mock.dump = function(object){
|
||||||
* @ngdoc object
|
* @ngdoc object
|
||||||
* @name angular.module.ngMock.$httpBackend
|
* @name angular.module.ngMock.$httpBackend
|
||||||
* @describe
|
* @describe
|
||||||
* Fake HTTP backend used by the $http service during testing. This implementation can be used to
|
* Fake version of `$httpBackend` service used by the `$http` service during unit testing.
|
||||||
* respond with static or dynamic responses via the `expect` and `when` apis and their shortcuts
|
*
|
||||||
* (`expectGET`, `whenPOST`, etc).
|
* 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 = [],
|
var definitions = [],
|
||||||
expectations = [],
|
expectations = [],
|
||||||
responses = [],
|
responses = [],
|
||||||
responsesPush = angular.bind(responses, responses.push),
|
responsesPush = angular.bind(responses, responses.push);
|
||||||
autoflush = false;
|
|
||||||
|
|
||||||
function createResponse(status, data, headers) {
|
function createResponse(status, data, headers) {
|
||||||
if (angular.isFunction(status)) return status;
|
if (angular.isFunction(status)) return status;
|
||||||
|
|
@ -638,7 +658,8 @@ angular.mock.$httpBackendDecorator = function($delegate, $defer) {
|
||||||
while ((definition = definitions[++i])) {
|
while ((definition = definitions[++i])) {
|
||||||
if (definition.match(method, url, data, headers || {})) {
|
if (definition.match(method, url, data, headers || {})) {
|
||||||
if (definition.response) {
|
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);
|
var response = definition.response(method, url, data, headers);
|
||||||
xhr.$$respHeaders = response[2];
|
xhr.$$respHeaders = response[2];
|
||||||
callback(response[0], response[1], xhr.getAllResponseHeaders());
|
callback(response[0], response[1], xhr.getAllResponseHeaders());
|
||||||
|
|
@ -656,17 +677,21 @@ angular.mock.$httpBackendDecorator = function($delegate, $defer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$httpBackend.when = function(method, url, data, headers) {
|
$httpBackend.when = function(method, url, data, headers) {
|
||||||
var definition = new MockHttpExpectation(method, url, data, headers);
|
var definition = new MockHttpExpectation(method, url, data, headers),
|
||||||
definitions.push(definition);
|
chain = {
|
||||||
return {
|
respond: function(status, data, headers) {
|
||||||
respond: function(status, data, headers) {
|
definition.response = createResponse(status, data, headers);
|
||||||
definition.response = createResponse(status, data, headers);
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
passThrough: function() {
|
if ($defer) {
|
||||||
|
chain.passThrough = function() {
|
||||||
definition.passThrough = true;
|
definition.passThrough = true;
|
||||||
}
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
|
definitions.push(definition);
|
||||||
|
return chain;
|
||||||
};
|
};
|
||||||
|
|
||||||
createShortMethods('when');
|
createShortMethods('when');
|
||||||
|
|
@ -701,15 +726,6 @@ angular.mock.$httpBackendDecorator = function($delegate, $defer) {
|
||||||
$httpBackend.verifyNoOutstandingExpectation();
|
$httpBackend.verifyNoOutstandingExpectation();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
$httpBackend.autoflush = function(val) {
|
|
||||||
if (arguments.length) {
|
|
||||||
autoflush = !!val;
|
|
||||||
} else {
|
|
||||||
return autoflush;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$httpBackend.verifyNoOutstandingExpectation = function() {
|
$httpBackend.verifyNoOutstandingExpectation = function() {
|
||||||
if (expectations.length) {
|
if (expectations.length) {
|
||||||
throw Error('Unsatisfied requests: ' + expectations.join(', '));
|
throw Error('Unsatisfied requests: ' + expectations.join(', '));
|
||||||
|
|
@ -836,13 +852,29 @@ function MockXhr() {
|
||||||
angular.module('ngMock', ['ng']).service({
|
angular.module('ngMock', ['ng']).service({
|
||||||
'$browser': angular.mock.$BrowserProvider,
|
'$browser': angular.mock.$BrowserProvider,
|
||||||
'$exceptionHandler': angular.mock.$ExceptionHandlerProvider,
|
'$exceptionHandler': angular.mock.$ExceptionHandlerProvider,
|
||||||
'$log': angular.mock.$logProvider
|
'$log': angular.mock.$logProvider,
|
||||||
}).init(function($provide) {
|
'$httpBackend': angular.mock.$HttpBackendProvider
|
||||||
$provide.decorator('$httpBackend', angular.mock.$httpBackendDecorator);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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){
|
window.jstestdriver && (function(window){
|
||||||
/**
|
/**
|
||||||
* Global method to output any number of objects into JSTD console. Useful for debugging.
|
* Global method to output any number of objects into JSTD console. Useful for debugging.
|
||||||
|
|
|
||||||
84
test/angular-mocksSpec.js
vendored
84
test/angular-mocksSpec.js
vendored
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
describe('mocks', function() {
|
describe('ngMock', function() {
|
||||||
|
|
||||||
describe('$browser', function() {
|
describe('$browser', function() {
|
||||||
|
|
||||||
|
|
@ -373,19 +373,12 @@ describe('mocks', function() {
|
||||||
|
|
||||||
|
|
||||||
describe('$httpBackend', function() {
|
describe('$httpBackend', function() {
|
||||||
var hb, callback, realBackendSpy;
|
var hb, callback;
|
||||||
|
|
||||||
beforeEach(inject(
|
beforeEach(inject(function($httpBackend) {
|
||||||
function($provide) {
|
callback = jasmine.createSpy('callback');
|
||||||
realBackendSpy = jasmine.createSpy('realBackend');
|
hb = $httpBackend;
|
||||||
$provide.value('$httpBackend', realBackendSpy);
|
}));
|
||||||
$provide.decorator('$httpBackend', angular.mock.$httpBackendDecorator)
|
|
||||||
},
|
|
||||||
function($httpBackend) {
|
|
||||||
callback = jasmine.createSpy('callback');
|
|
||||||
hb = $httpBackend;
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
|
|
||||||
it('should respond with first matched definition', function() {
|
it('should respond with first matched definition', function() {
|
||||||
|
|
@ -681,31 +674,8 @@ describe('mocks', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('definitions with passThrough delegation', function() {
|
it('should not have passThrough method', function() {
|
||||||
it('should delegate requests to the real backend when passThrough is invoked', function() {
|
expect(hb.passThrough).toBeUndefined();
|
||||||
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();
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue