Angular resource testing: $httpBackend.flush() cause Unexpected request

旧城冷巷雨未停 提交于 2019-12-20 14:12:37

问题


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 getting undefined from address. I saw examples: example all use the flush() 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'

回答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');
        }));
    });
});



回答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.



来源:https://stackoverflow.com/questions/16722666/angular-resource-testing-httpbackend-flush-cause-unexpected-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!