4

我正在尝试为 ui-router 的状态编写单元测试,但无法让它工作,以便$state.current在我调用$state.transitionTo()内部测试后在控制器内部包含正确的状态。

这适用于浏览器(transitionToui-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;
})

;

这是测试代码(Jasmine)about.spec.js

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 的测试,看起来他们做的事情完全一样(那里$q.flush()是装饰的$rootScope.$digest()),所以我想这应该可行。

有什么提示吗?(到目前为止,我对一切都有角度的东西有点菜鸟:)

4

2 回答 2

2

您是否考虑过在方法中使用$rootScope.$apply()而不是?$rootScope.$digest()createController

于 2013-11-25T21:54:24.120 回答
0

请记住,ui 路由器将初始化您的控制器并将范围对象注入其中,而在此测试中,您实例化了您自己的控制器并传递您自己的范围对象。您的控制器与 ui 路由器实例化的控制器不同,因此它们的范围对象也是不同的引用。
我想如果你需要“单元测试”一个 ui-router 然后只测试状态参数,而不是控制器内的范围对象。如果您需要测试作用域对象,请为控制器创建一个单元测试。

于 2014-03-05T22:58:17.707 回答