angularJS $ stateProvider:如何在UI-Router中单元测试不同的视图?

shr*_*nsh 6 unit-testing angularjs angular-ui-router angular-templatecache

如何针对以下场景对不同视图进行单元测试

.state('app.sr.product.upload', {
            name: 'upload',
            url: '/upload',
            data: {
                tags: [],
                userCommunities: []
            },
            views: {
                "productView@app.sr.product": {
                    templateUrl: 'views/upload/upload.html',
                    controller: 'UploadCtrl',
                    controllerAs: 'ul'
                },
                "tags@app.sr.product.upload": {
                    templateUrl: 'views/tags/tags.html',
                    controller: 'TagsCtrl',
                    controllerAs: 'vm'
                },
                "UserCommunityPanel@app.sr.product.upload": {
                    templateUrl: 'views/user-community/user-community.html',
                    controller: 'UserCommunityCtrl',
                    controllerAs: 'ul'
                },
            }
        })
Run Code Online (Sandbox Code Playgroud)
  • 如果我的观点是tags@app.sr.product.upload那么我如何测试我的控制器是TagsCtrl,我的控制器值是vm等?

  • 我怎么能单元测试,如果我的状态是app.sr.product.uploaddata.tags=[], data.userCommunities=[]等等.

我搜索了很多文档和教程,但没有得到它.

任何帮助都很明显.谢谢

Twi*_*ron 5

尝试这个尺寸.我假设您将使用茉莉花进行测试,但任何测试框架的概念都是相同的.

运行测试时,首先订阅该'$stateChangeSuccess'事件,然后导航到该状态.一旦事件触发,请检查toState值以查看它们是否符合您的预期.

您可以运行代码段以查看正在运行的测试.

//write a unit test
describe('state changes', function() {
  beforeEach(module('app'));
  var $rootScope, $state;
  beforeEach(inject(function(_$rootScope_, _$state_) {
    // The injector unwraps the underscores (_) from around the parameter names when matching
    $rootScope = _$rootScope_;
    $state = _$state_;
  }));


  it('loads page 1', function(done) {
    //wait for the state to change, then make sure we changed to the correct state
    $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
      expect(toState.controller).toEqual('Controller1');
      done();
    });
    //navigate to the state
    $state.go('state1');
    //start a digest cycle so ui-router will navigate
    $rootScope.$apply();
  });

  it('loads page 2', function(done) {
    //wait for the state to change, then make sure we changed to the correct state
    $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
      expect(toState.controller).toEqual('Controller2');
      done();
    });
    //navigate to the state
    $state.go('state2');
    //start a digest cycle so ui-router will navigate
    $rootScope.$apply();
  });

  it('loads page 3', function(done) {
    //wait for the state to change, then make sure we changed to the correct state
    $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
      expect(toState.controller).toEqual('Controller3');
      done();
    });
    //navigate to the state
    $state.go('state3');
    //start a digest cycle so ui-router will navigate
    $rootScope.$apply();
  });
});

//set up some dummy controllers and some dummy states
angular.module('app', ['ui.router']).controller('Controller1', function() {
  this.message = 'Page 1';
}).controller('Controller2', function() {
  this.message = 'Page 2';
}).controller('Controller3', function() {
  this.message = 'Page 3';
}).config(function($stateProvider, $urlRouterProvider) {
  $urlRouterProvider.otherwise("/state1");

  $stateProvider.state('state1', {
    url: "/state1",
    controller: 'Controller1',
    controllerAs: 'vm',
    template: '<h1>{{vm.message}}</h1>'
  }).state('state2', {
    url: "/state2",
    controller: 'Controller2',
    controllerAs: 'vm',
    template: '<h2>{{vm.message}}</h2>'
  }).state('state3', {
    url: "/state3",
    controller: 'Controller3',
    controllerAs: 'vm',
    template: '<h3>{{vm.message}}</h3>'
  });
});
Run Code Online (Sandbox Code Playgroud)
h1 {
  color: red;
}
h2 {
  color: blue;
}
h3 {
  color: green;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>

<script src="
https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.js"></script>
<link rel="stylesheet" type="text/css" href="http://jasmine.github.io/2.0/lib/jasmine.css">
<script src="http://jasmine.github.io/2.0/lib/jasmine.js"></script>
<script src="http://jasmine.github.io/2.0/lib/jasmine-html.js"></script>
<script src="http://jasmine.github.io/2.0/lib/boot.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-mocks.js"></script>
<div ng-app="app">
  <a ui-sref="state1">State 1</a>
  <a ui-sref="state2">State 2</a>
  <a ui-sref="state3">State 3</a>
  <div ui-view></div>
</div>
Run Code Online (Sandbox Code Playgroud)


m1g*_*u3l 0

这不是我通常会进行单元测试的东西。UI-Router 本身已被测试很好地覆盖

您最好使用Protractor进行 e2e(端到端)测试。您模拟点击链接,您期望 url 是这样,使用期望列表中的元素数量是这样等等。

但如果你真的需要它:

  • 定位每个视图的根元素(通过添加特定类并使用选择器)
  • 您应该能够通过 angular.element 包装器方法访问作用域和控制器