我正在尝试为ui-router的状态编写单元测试,并且无法使其工作,以便在我在测试中调用$state.current
之后$state.transitionTo()
在控制器内包含正确的状态。
这适用于浏览器(其中transitionTo
在内部由ui-router
调用),但不在单元测试中(使用Karma) - 我明确地称之为。
这是控制器的代码:
angular.module( 'ngBoilerplate.about', [
'ui.router'
])
.config(function config( $stateProvider ) {
$stateProvider.state( 'about', {
url: '/about',
views: {
"main": {
controller: 'AboutCtrl',
templateUrl: 'about/about.tpl.html'
}
},
data: {
title: "About"
}
});
})
.controller( 'AboutCtrl', function AboutCtrl( $scope, $state ) {
console.log($state.get('about'));
console.log($state.current);
$scope.title = $state.current.data.title;
})
;
以下是about.spec.js
中的测试代码(Jasmine):
describe( 'AboutCtrl', function() {
var $scope, createController;
beforeEach( module( 'ngBoilerplate.about' ) );
beforeEach( inject( function( $controller, $rootScope, $state, $stateParams) {
$scope = $rootScope.$new();
createController = function() {
$state.transitionTo('about', {});
$rootScope.$digest();
return $controller( 'AboutCtrl', { $scope: $scope, $state: $state });
};
}));
it( 'should have title for about set', inject( function() {
var controller = createController();
expect($scope.title).toEqual('About');
}));
});
这会产生结果:
LOG: Object{url: '/about', views: Object{main: Object{controller: ..., templateUrl: ...}}, data: Object{title: 'About1'}, name: 'about'}
LOG: Object{name: '', url: '^', views: null, abstract: true}
Chrome 29.0.1547 (Linux) AboutCtrl should have title for about set FAILED
TypeError: Cannot read property 'title' of undefined
这表明状态正常,但由于某种原因它没有改变,保持在大致初始化的状态。再说一遍:在真实应用环境中调用此代码时,会显示正确填充的$state.current
,其中包含所有数据等。
我查看了ui-router
's tests,看起来他们做的完全相同($q.flush()
是装饰的$rootScope.$digest()
),所以我想这应该有效。
任何提示? (到目前为止,我对所有角色都有一点点菜鸟。)
答案 0 :(得分:2)
您是否考虑在$rootScope.$apply()
方法中使用$rootScope.$digest()
代替createController
?
答案 1 :(得分:0)
请记住,ui路由器将初始化您的控制器并将范围对象注入其中,而在此测试中,您实例化您自己的控制器传递您自己的范围对象。您的控制器与ui路由器实例化的控制器不同,因此它们的范围对象也是不同的引用 我想如果你需要“单元测试”一个ui-router,那么只测试状态参数,但不测试控制器内的范围对象。如果需要测试作用域对象,请为控制器创建单元测试。