karma/angularjs how to test run block with an asynchronous service

為{幸葍}努か 提交于 2019-12-12 04:49:10

问题


How can I test like:

init.js lama.system module

angular.module('lama.system', [])
   .config(['$httpProvider', function($httpProvider) {
        // Crossdomain requests not allowed if you want do cors request see filter.php 
        $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
    }])
    .run(['$rootScope', '$state', '$log', 'Global',function ($rootScope, $state, $log, Global) {
        $rootScope.$state = $state;
        $rootScope.$log = $log;
        $rootScope.global = Global;
    }]);

controllers.js lama.system module

angular.module('lama.system')
    .controller('SystemController', ['$scope',
        function($scope) {
           $scope.test =[];

         }
    ]);

services.js lama.system module

angular.module('lama.system')
    .factory('Menus', ['$http', function($http) {
        return {
            query : function(menus){
                return $http.get('/api/v1/user/menus', {
                    params: {
                        'menus[]': menus
                    }
                });
            }
        }; 
    }]);

system.js router

//Setting up route
angular.module('lama.system')
    .config(['$stateProvider', '$urlRouterProvider',
        function($stateProvider, $urlRouterProvider) {
            $urlRouterProvider.otherwise('/');
            $stateProvider              
            .state('home', {
                url: '/',
                templateUrl: 'system/views/home.html',
                controller:'SystemController'
            });
        }
    ]);

init.js lama module

angular.module('lama', ['ui.router','restangular','lama.system','lama.users'])
    .run(['$rootScope',  'Menus',function ($rootScope, Menus) {
       // Default hard coded menu items for main menu
           var menus = [
            {
                'permission': null,
                'title': 'Home',
                'link': 'home'
            },
            {
                'permission': 'users',
                'title': 'User',
                'link': 'user_actions.list'
            }
            ];

            $rootScope.menus = [];

            function queryMenu(menus) {
                Menus.query(menus).then(
                    function (result) {
                        $rootScope.menus = result.data; 
                    },
                    function (reason) {
                        throw new Error(reason);
                    }
                    );
            }

            // Query server for menus and check permissions
            queryMenu(menus);

           $rootScope.$on('loggedin', function(event,user) {
                console.log('kkk');
                queryMenu(menus);

                $rootScope.global = {
                    user:  user,
                    authenticated: user.groups.length,
                    isAdmin:  user.groups.indexOf('Admins')
                };
            });


    }]);

The test

(function() {
    describe('Unit test: system module', function () {
        describe('SystemController', function () {

            // load the controller's module
            beforeEach(function() {
                module('lama');
                module('stateMock');
            });

            var SystemController,
            $rootScope,
            $scope,
            $httpBackend;

            // Initialize the controller and a mock scope
            beforeEach(inject(function ($controller, _$rootScope_, _$httpBackend_) {
                $rootScope = _$rootScope_;
                $scope = _$rootScope_.$new();
                $httpBackend = _$httpBackend_;
                SystemController = $controller('SystemController', {
                    $scope: $scope
                });
                $httpBackend.when('GET', '/api/v1/user/menus').respond(200,{});
            }));

            it('should attach a list of awesomeThings to the scope', function () {
                expect($scope.test.length).toBe(0);
            });

            it('should expose some global scope', function() {
                expect($rootScope.global).toBeTruthy();
            });
        });

    });
}());

that give me :(

grunt test
Running "karma:unit" (karma) task
INFO [karma]: Karma v0.12.21 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
WARN [watcher]: Pattern "/home/whisher/public_html/public/users/tests/unit/**/*.js" does not match any file.
INFO [PhantomJS 1.9.7 (Linux)]: Connected on socket zK1SplAjTHe4x5sAM9ew with id 16331650
WARN [web-server]: 404: /api/v1/user/menus?menus%5B%5D=%7B%22permission%22:null,%22title%22:%22Home%22,%22link%22:%22home%22%7D&menus%5B%5D=%7B%22permission%22:%22users%22,%22title%22:%22User%22,%22link%22:%22user_actions.list%22%7D
WARN [web-server]: 404: /system/views/home.html
ERROR: 'Error: [object Object]
    at http://localhost:9876/base/public/init.js?c7a481724bcf81e4810141349c93d0f698a18904:34
    at http://localhost:9876/base/public/bower_components/angular/angular.min.js?4b4cffd940f7a29168096212664973432d1d7449:100
    at http://localhost:9876/base/public/bower_components/angular/angular.min.js?4b4cffd940f7a29168096212664973432d1d7449:100
    at http://localhost:9876/base/public/bower_components/angular/angular.min.js?4b4cffd940f7a29168096212664973432d1d7449:101
    at http://localhost:9876/base/public/bower_components/angular/angular.min.js?4b4cffd940f7a29168096212664973432d1d7449:112
    at http://localhost:9876/base/public/bower_components/angular/angular.min.js?4b4cffd940f7a29168096212664973432d1d7449:109
    at http://localhost:9876/base/public/bower_components/angular/angular.min.js?4b4cffd940f7a29168096212664973432d1d7449:112
    at h (http://localhost:9876/base/public/bower_components/angular/angular.min.js?4b4cffd940f7a29168096212664973432d1d7449:72)
    at x (http://localhost:9876/base/public/bower_components/angular/angular.min.js?4b4cffd940f7a29168096212664973432d1d7449:77)
    at http://localhost:9876/base/public/bower_components/angular/angular.min.js?4b4cffd940f7a29168096212664973432d1d7449:78'
PhantomJS 1.9.7 (Linux): Executed 2 of 2 SUCCESS (0.039 secs / 0.065 secs)

Done, without errors.

NB

I'm using ui-router


回答1:


I've taken a look at your source code. The primary offending item is:

angular.element(document).ready(function() {
  angular.bootstrap(document, ['lama']);
});

By including your manual bootstrap in the files that karma imports, your app is un-necessarily being bootstrapped within the karma test environment. So, instead, move your lama module into a separate file, and omit init.js from your files to be included by karma.

There are also a couple of other design concerns that are causing excessive test setup. When testing SystemController there is no need to include anything but the lama.system module (as this is what the controller belongs to). Your test setup for this controller can be as simple as:

var $scope, $rootScope;

beforeEach(module('system.lama'));

beforeEach(inject(function($controller, _$rootScope_) {
  $rootScope = _$rootScope_;
  $scope = $rootScope.$new();
  $controller('SystemController', {$scope: $scope});
}));

You will note that in isolating the lama.system module as above, you will get an error that $state cannot be injected (not found). This is because your module definition should instead be:

angular.module('lama.system', ['ui.router'])

(A module should not require the presence of another module for its own dependencies, else it can never function in isolation).

One final observation on your mocking for the lama module run block. Strictly speaking you should stub the service query method entirely and not just part of its implementation, else your test is completely isolated. Therefore, instead, it would be better to do the following:

beforeEach(module(function($provide) {
  $provide.decorator('Menus', function($delegate, $q) {
     // overwrite the query method
     $delegate.query = function() {
       return $q.when([{id: 1, name: 'Bob'}]);
     };    
     return $delegate; 
  });
}));

This way, you don't need to worry about using $httpBackend at all.



来源:https://stackoverflow.com/questions/25363969/karma-angularjs-how-to-test-run-block-with-an-asynchronous-service

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