Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用Angular.js+;用户界面路由器_Javascript_Angularjs_Karma Runner_Angular Ui Router - Fatal编程技术网

Javascript 使用Angular.js+;用户界面路由器

Javascript 使用Angular.js+;用户界面路由器,javascript,angularjs,karma-runner,angular-ui-router,Javascript,Angularjs,Karma Runner,Angular Ui Router,我想知道如何使用Angular.js+UI路由器进行Karma测试 我定义了以下状态:它有两个解析,用于获取一些数据并为控制器准备数据。(来自余烬背景,这很有道理。) 我们的UserIndexCtrl如下所示:(它将解析的状态模型分配给$scope,以便视图可以使用它) 这在浏览器中工作得很好,我看到了正确的结果。然而,当涉及到测试时,它给了我奇怪的错误 下面是一个Karma单元测试示例: describe('controllers', function () { var $httpBac

我想知道如何使用Angular.js+UI路由器进行Karma测试

我定义了以下状态:它有两个解析,用于获取一些数据并为控制器准备数据。(来自余烬背景,这很有道理。)

我们的UserIndexCtrl如下所示:(它将解析的状态模型分配给$scope,以便视图可以使用它)

这在浏览器中工作得很好,我看到了正确的结果。然而,当涉及到测试时,它给了我奇怪的错误

下面是一个Karma单元测试示例:

describe('controllers', function () {

  var $httpBackend
    , $rootScope
    , $scope
    , $state
    , $httpBackend
    , $controller

  beforeEach(module('app'))

  beforeEach(inject(function ($injector) {
    $state = $injector.get('$state')
    $rootScope = $injector.get('$rootScope')
    $httpBackend = $injector.get('$httpBackend')
    $scope = $rootScope.$new()
    $controller = $injector.get('$controller')
  }))

  it('UserIndexCtrl should exist', inject(function () {
    $httpBackend
      .expect('GET', '/api/users')
      .respond(200, {users: [ {}, {}, {} ]})

    $state.go('users')
    $rootScope.$apply()

    $controller('AdminZonesIndexCtrl', { $scope: $scope, $state: $state });
    $rootScope.$apply()
    assert.equal($scope.users.length, 3)
  }))

})
我看到:

[$injector:unpr] Unknown provider: stateModelsProvider <- stateModels
http://errors.angularjs.org/1.3.0-build.2937+sha.4adc44a/$injector/unpr?p0=stateModelsProvider%20%3C-%20stateModels
Error: [$injector:unpr] Unknown provider: stateModelsProvider <- stateModels
http://errors.angularjs.org/1.3.0-build.2937+sha.4adc44a/$injector/unpr?p0=stateModelsProvider%20%3C-%20stateModels

[$injector:unpr]未知提供程序:stateModelsProvider出现错误的原因是,您首先转换到一个状态,该状态使用一个新范围实例化您的
用户sindexCtrl
,然后在测试中创建另一个控制器实例(同样,使用一个新范围)。两者相互独立,在第二种情况下,
stateModels
是未知/不可用的依赖项

因此,虽然您的想法是有效的测试关注点,但在尝试将这三个问题结合在一起时,您实际上是在单元测试环境中执行端到端测试。您不应该这样做-这样做会对以下内容产生脆弱的依赖:

  • 属于“用户”状态的控制器
  • 在状态转换的某个地方调用了一个特定的http请求
  • stateModels依赖项绑定到范围
在这些断言中,控制器只关心最后一个。控制器的单元测试不关心它是如何/何时实例化的,也不关心
stateModels
依赖项来自何处,它们只关心控制器自身的行为。所以,让我们把这种行为分成两部分:

对控制器进行单元测试

您的第一次测试应简化为以下内容:

it('binds the users to the scope', function(){
   var stateModels = [{}, {}, {}];
   $controller('UserIndexCtrl', {$scope: $scope, stateModels: stateModels});
   assert.equal($scope.users, stateModels);
});
请注意,当您添加更多测试时,您可能希望将控制器实例化移动到每个
块之前的

测试路线

测试路由的问题实际上是应用程序行为的问题,对此您应该遵从。但是,如果您特别希望对状态执行单元测试,那么最好通过测试状态本身的配置来实现。例如:

it('resolves the stateModels dependency', function() {
   var state = $state.get('users');
   assert.isDefined(state.resolve.stateModels); 
   // perform assertion that stateModels function resolves to what is expected
   // Note: any such assertion should stub any dependency being used, to ensure
   // we are testing in isolation.
});

尽管如此,我个人并不选择单元测试路由/路由配置,而是通过使用量角器进行e2e测试来获得这种覆盖。

这很好地总结了我的问题。@scarlz,我是摩卡柴的新手,你能帮我解决类似的问题吗。
it('binds the users to the scope', function(){
   var stateModels = [{}, {}, {}];
   $controller('UserIndexCtrl', {$scope: $scope, stateModels: stateModels});
   assert.equal($scope.users, stateModels);
});
it('resolves the stateModels dependency', function() {
   var state = $state.get('users');
   assert.isDefined(state.resolve.stateModels); 
   // perform assertion that stateModels function resolves to what is expected
   // Note: any such assertion should stub any dependency being used, to ensure
   // we are testing in isolation.
});