Angular resource testing: $httpBackend.flush() cause Unexpected request
Solution 1
I have finally found solution:
I tried to follow this: other post
So I added $templateCache
:
'use strict';
var $httpBackend;
describe('Service: AddressService', function () {
beforeEach(module('myApp'));
beforeEach(inject(function ($injector, $templateChache) {
$templateCache.put('views/home.html', '.<template-goes-here />');
var url_get = 'api/v1/models/address/5';
var response_get = {
address_line_1: '8 Austin House Netly Road',
address_line_2: 'Ilford IR2 7ND'
};
$httpBackend = $injector.get('$httpBackend');
$httpBackend.whenGET(url_get).respond(response_get);
}));
describe('AddressService get test', function () {
it('Tests get address', inject(function (AddressService) {
var address = AddressService.get({ id: '5'});
$httpBackend.flush();
expect(address.address_line_1).toEqual('8 Austin House Netly Road');
expect(address.address_line_2).toEqual('Ilford IR2 7ND');
}));
});
});
Solution 2
the error is caused by your test attempting to load the main page for your app. Since you have not told the test to expect this server call, an error is returned. See the documentation for $httpBackend for clarification on this point.
Your $templateCache workaround is designed for unit testing directives not anything else. You were quite close with:
$httpBackend.when('GET', /\.html$/).passThrough();
Since you don't need to do anything with the actual template file it's a safe and simple work around to add this to your beforeEach() block.
$httpBackend.whenGET(/\.html$/).respond('');
This stops you getting the TypeError you had.
TypeError: Object #<Object> has no method 'passThrough'
I had the same issue in my unit tests after upgrading to a new version of Angular JS and using respond('')
worked fine.
Bartosz Dabrowski
Software development is all about making decisions - eventually. Programmer makes several or even a hundred choices that impact the product in a single day. Making decisions are the most difficult tasks that we encounter but what is possible if we get them right?
Updated on June 13, 2022Comments
-
Bartosz Dabrowski almost 2 years
I want to test angularjs resource.
'use strict'; /** * AddressService provides functionality to use address resource in easy way. * * This is an example usage of method: * * `get`: * var a = AddressService.get({id: '1'}, function (data) { // Work here with your resource } ); * */ App.factory('AddressService', function ($resource, $rootScope) { var url = [ $rootScope.GLOBALS.API_PATH, $rootScope.GLOBALS.API_VERSION, 'models/address/:id' ].join('/'), actions = { 'get': { method: 'GET', params: {id: '@id'} } }; return $resource(url, {}, actions); });
I created the test:
'use strict'; var $httpBackend; describe('Service: AddressService', function () { beforeEach(module('myApp')); beforeEach(inject(function ($injector) { var url_get = 'api/v1/models/address/5'; var response_get = { address_line_1: '8 Austin House Netly Road', address_line_2: 'Ilford IR2 7ND' }; $httpBackend = $injector.get('$httpBackend'); $httpBackend.whenGET(url_get).respond(response_get); })); describe('AddressService get test', function () { it('Tests get address', inject(function (AddressService) { var address = AddressService.get({ id: '5'}); $httpBackend.flush(); expect(address.address_line_1).toEqual('8 Austin House Netly Road'); expect(address.address_line_2).toEqual('Ilford IR2 7ND'); })); }); });
I am not experienced with angular very well. I have set jasmine in karma.config.js. AngularJS v1.0.6 Yoeman and Grunt manage project.
I try
grunt test
Running "karma:unit" (karma) task INFO [karma]: Karma server started at http://localhost:8080/ INFO [launcher]: Starting browser Chrome INFO [Chrome 27.0 (Linux)]: Connected on socket id RFFUY5bW8Hb5eTu0n-8L Chrome 27.0 (Linux) Service: AddressService AddressService get Tests get address FAILED Error: Unexpected request: GET views/home.html No more request expected at Error (<anonymous>) at $httpBackend (/home/bart/y/projects/x/frontend/app/components/angular-mocks/angular-mocks.js:910:9) at sendReq (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:9087:9) at $http (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:8878:17) at Function.$http.(anonymous function) [as get] (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:9021:18) at $q.when.then.then.next.locals (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:7394:34) at wrappedCallback (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:6797:59) at wrappedCallback (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:6797:59) at /home/bart/y/projects/x/frontend/app/components/angular/angular.js:6834:26 at Object.Scope.$eval (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:8011:28) Error: Declaration Location at window.jasmine.window.inject.angular.mock.inject (/home/bart/y/projects/x/frontend/app/components/angular-mocks/angular-mocks.js:1744:25) at null.<anonymous> (/home/bart/y/projects/x/frontend/test/spec/services/userdata/AddressService.js:32:30) at null.<anonymous> (/home/bart/y/projects/x/frontend/test/spec/services/userdata/AddressService.js:31:5) at /home/bart/y/projects/x/frontend/test/spec/services/userdata/AddressService.js:5:1 .................................................................. Chrome 27.0 (Linux): Executed 67 of 67 (1 FAILED) (0.343 secs / 0.179 secs) Warning: Task "karma:unit" failed. Use --force to continue.
If I remove
$httpBackend.flush()
in test. Test is passing. But I am gettingundefined
fromaddress
. I saw examples: example all use theflush()
But only I get silly exception:Error: Unexpected request: GET views/home.html
views/home.html
is my view in project directory. I have no idea how solve my problem I could not find any solution. Am I missing the point somehow?Can anybody see mistake in my code? All suggestions will be appreciate.
EDIT
I have found that I need to use this:
$httpBackend.when('GET', /\.html$/).passThrough();
But another problem is I am getting:
TypeError: Object #<Object> has no method 'passThrough'
-
Paolo del Mundo over 10 yearsWhy is the templateCache important? It seems it has nothing to do with an API service.
-
Pwnna over 10 yearsI agree. This seems like an awful hack to ignore the problem. I'm encountering the same issues now and I'm not sure why this is the case...
-
Bartosz Dabrowski about 10 yearsThese are unit tests and you have to extract specific units (service in this case) to test. Remove all other dependencies even templates which are simply mocked here. I don't know better way to do it have no idea about core angular flow either. And this question isn't closed yet.
-
Stephane about 9 yearsIsn't it possible instead to avoid the $http service making such a request to the application main page ?
-
akostadinov over 3 yearsThis is a nice simple resolution to fix individual test cases and I will probably stick to it. For more ideas check github.com/meanjs/mean/issues/198