【问题标题】:Unit Testing UI Router With Resolve使用 Resolve 对 UI 路由器进行单元测试
【发布时间】:2016-05-06 22:54:20
【问题描述】:

我正在尝试使用 resolve 为我的 ui-router 编写单元测试。

Router.js

define(['module', 'require'], function(module, require) {
    'use strict';

    var Router = function ($stateProvider, $urlRouterProvider) {

        $urlRouterProvider.otherwise('/shopping');

        $stateProvider
            .state('shopping', {
                url: '/shopping',
                templateUrl: 'app/shopping.html',
                resolve:{
                    userFactory : 'UserFactory',
                    checkAccess:function(userFactory){
                        return userFactory.checkUser();
                    }
                }
            })
            .state('products', {
                url: '/products',
                templateUrl: 'app/products.html',
                resolve:{
                    userFactory : 'UserFactory',
                    checkAccess:function(userFactory){
                        return userFactory.checkUser();
                    }
                }
            })
            .state('notAuth', {
                url: '/notAuth',
                templateUrl: 'app/unauthorised.html'
            });
    };

    module.exports = ['$stateProvider', '$urlRouterProvider', Router];
});

在 userFactory.checkUser() 内;我基本上检查了用户的权限,然后重定向到 templateUrl,或者执行:

$state.go('notAuth');

我当前的 .spec.js:

define(['require', 'angular-mocks', 'angular-ui-router', 'app/router'], function (require) {
    'use strict';
    describe('myApp/myState', function() {

        var $rootScope, $state, $injector, myServiceMock, $httpBackend, state = 'shopping';

        var mockResponse = {
            "access": true
        }

        var angular = require('angular');
        var myRouter = require('app/router');

        beforeEach(module('ui.router'));

        beforeEach(function() {

            module(myRouter, function($provide) {
                $provide.value('userFactory', myServiceMock = {});
            });

            inject(function(_$rootScope_, _$state_, _$injector_, $templateCache, _$httpBackend_) {
                $rootScope = _$rootScope_.$new();
                $state = _$state_;
                $injector = _$injector_;
                $httpBackend = _$httpBackend_;
                $rootScope.$digest();
            })
        });

        it('should transition to shopping', inject(function($state,$rootScope){
            $state.transitionTo('shopping');
            $rootScope.$apply();
            expect($state.current.name).toBe('shopping');
        }));

        it('should resolve data', function() {
            myServiceMock.checkUser = jasmine.createSpy('checkUser').and.returnValue(mockResponse);
            // earlier than jasmine 2.0, replace "and.returnValue" with "andReturn"

            $state.go(state);
            $rootScope.$digest();
            expect($state.current.name).toBe(state);
        });
    });
});

通过上述测试,我得到以下错误:

Information:  myApp/myState
Information:    should transition to shopping   Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Information:    Watchers fired in the last 5 iterations: []
Information:    http://errors.angularjs.org/1.4.0/$rootScope/infdig?p0=10&p1=%5B%5D

Information:    should resolve data Expected '' to be 'shopping'.

【问题讨论】:

    标签: angularjs angular-ui-router jasmine karma-runner karma-jasmine


    【解决方案1】:

    这里似乎发生了一些事情。首先,你消化了太多次。这就是“达到 10 个 $digest() 迭代”的消息。要解决这个问题,您应该从注入函数的末尾删除 $rootScope.$digest()

    我认为实际失败的测试部分是因为您没有解决您在路线中配置的checkAccess 解决方案。尝试将$provide.value('checkAccess', function() {return true;}); 添加到您的$provide.value 设置中。这应该允许 checkAccess 在您的路由中解析,这将允许路由完成状态转换。

    我在这里找到了类似问题的答案:Angular Jasmine UI router inject resolve value into test

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-16
      • 2020-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-30
      相关资源
      最近更新 更多