【问题标题】:AngularJS, route resolve, location change, unit tests, karma-jasmineAngularJS、路由解析、位置更改、单元测试、因果报应
【发布时间】:2016-03-23 14:46:21
【问题描述】:

在 Angular 中,我为所有操作编写了路由解析,以检查您是否已登录

$routeProvider.when('/home', {
    resolve: {
        Authenticated: function($location, AuthAuthenticator, AuthIdentity) {
            return new Promise(function(resolve, reject) {
                AuthAuthenticator.init().then(
                    function( success ) {
                        if (!AuthAuthenticator.isAuthenticated() ) {
                            $location.path("/login");
                            resolve( true );
                        }
                        resolve( false );
                    },
                    function( error ) {
                        reject( error );
                    }
                );
            });
        }
    }
});

如果您未登录,我们会将您重定向到登录页面。现在我想在我们的 karma-jasmine 单元测试中对此进行测试。但是如果我编写测试,location.path 不会改变。

describe('LoginController', function() {
    beforeEach(module('dcApp'));

    beforeEach(function() {
        var _authenticated = false;

        AuthAuthenticatorMock = {
            isAuthenticated: function() {
                return _authenticated
            },

            setAuthenticated: function( authenticated ) {
                _authenticated = authenticated;
            },
        };

        module( function( $provide ) {
            $provide.value('AuthAuthenticator', AuthAuthenticatorMock);
        });
    });

    var $controller;

    beforeEach(inject(function( _$route_, _$location_, _$controller_, _AuthAuthenticator_ ){
        // The injector unwraps the underscores (_) from around the parameter names when matching
        $route = _$route_;
        $location = _$location_;
        $controller = _$controller_;
        AuthAuthenticator = _AuthAuthenticator_;
    }));

    describe('Controller activation', function() {
        it ('redirects to login if user is not yet logged in', function() {
            AuthAuthenticator.setAuthenticated( false );
            var $scope = {};
            var controller = $controller('HomeController', { $scope: $scope });
            expect( $location.path() ).toBe('/login');
        });
    });

});

但结果是:

PhantomJS 2.1.1 (Linux 0.0.0) HomeController Controller activation redirects to login if user is not yet logged in FAILED
Expected '' to be '/login'.

现在我看到了一些关于 spy 的文档,但我不知道如何检查这个位置变化。

【问题讨论】:

    标签: angularjs unit-testing karma-jasmine


    【解决方案1】:

    您可以通过在 before eaches 发生后自己调用 resolve 来正确测试这一点。

    describe('LoginController', function() {
        beforeEach(module('dcApp'));
    
        beforeEach(function() {
            var _authenticated = false;
    
            AuthAuthenticatorMock = {
                isAuthenticated: function() {
                    return _authenticated
                },
    
                setAuthenticated: function( authenticated ) {
                    _authenticated = authenticated;
                },
            };
    
            module( function( $provide ) {
                $provide.value('AuthAuthenticator', AuthAuthenticatorMock);
            });
        });
    
        beforeEach( function() {
            var _path = '';
    
            locationMock = {
                path: function( argument ) {
                    if (argument) {
                        _path = argument;
                    }
                    return _path;
                }
            };
    
            module( function( $provide ) {
                $provide.value('$location', locationMock );
            });
        });
    
        var $controller;
    
        beforeEach(inject(function( _$route_, _$location_, _$controller_, _AuthAuthenticator_ ){
            // The injector unwraps the underscores (_) from around the parameter names when matching
            $route = _$route_;
            $location = _$location_;
            $controller = _$controller_;
            AuthAuthenticator = _AuthAuthenticator_;
        }));
    
        describe('Controller activation', function() {
            it ('redirects to login if user is not yet logged in', function() {
                AuthAuthenticator.setAuthenticated( false );
                var resolveTest = $route.routes['/home'].resolve.Authenticated;
                $injector.invoke( resolveTest );
            // if it's a promise call apply
                $rootScope.$apply();
                expect( $location.path() ).toBe('/login');
            });
        });
    
    });
    

    【讨论】:

      猜你喜欢
      • 2013-04-06
      • 2014-04-29
      • 1970-01-01
      • 2014-06-11
      • 1970-01-01
      • 1970-01-01
      • 2017-04-04
      • 2020-08-15
      • 2017-10-26
      相关资源
      最近更新 更多