【问题标题】:Unknown provider: $scopeProvider <- $scope未知提供者:$scopeProvider <- $scope
【发布时间】:2017-04-07 09:04:10
【问题描述】:

我正在尝试进行一项小型测试工作,以验证控制器是否已定义。

我收到的错误是:

myApp.orders module Order controller should .... FAILED
    Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope <- OrdersCtrl

读取类似的错误与依赖关系有关,但我不知道是什么问题。

控制器:

'use strict';

angular.module('myApp.orders', ['ngRoute'])

.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/orders', {
    templateUrl: 'orders/orders.template.html',
    controller: 'OrdersCtrl'
  });
}])

.controller('OrdersCtrl', function($scope, $location) {
  $scope.changeView = function(view){
    $location.path(view); // path not hash
  }
});

测试:

'use strict';

describe('myApp.orders module', function() {

  beforeEach(module('myApp.orders'));

  describe('Order controller', function(){

    it('should ....', inject(function($controller) {
      //spec body
      var OrdersCtrl = $controller('OrdersCtrl');
      expect(OrdersCtrl).toBeDefined();
    }));

  });
});

【问题讨论】:

  • 应该不是这样,但是你可以试试 .controller('OrdersCtrl', ['$scope','$location',function($scope, $location) { $scope. changeView = function(view){ $location.path(view); // 路径不是哈希 } }]);

标签: angularjs unit-testing inject


【解决方案1】:

这是因为您在测试中创建控制器时没有在控制器内部传递 $scope 变量。控制器尝试定义 $scope.changeView,但发现 $scope 未定义。 您需要在测试中将 $scope 变量传递给控制器​​。

var $rootScope, $scope, $controller;

beforeEach(function() {
    module('myApp.orders');

    inject(function (_$rootScope_, _$controller_) {
        $rootScope = _$rootScope_;
        $scope = _$rootScope_.$new();
        $controller = _$controller_;
    });
});

在你的测试中,

var OrdersCtrl = $controller('OrdersCtrl', { $scope: $scope });

【讨论】:

  • 这行得通,但我不明白为什么官方指南中的测试:docs.angularjs.org/guide/controller 不起作用?你能解释一下吗?
  • @DowinskiField 正如您在文档中的测试中看到的那样。您需要将 $scope, 传递给控制器​​,因为控制器需要它。要创建新的 $scope,您需要通过 $rootScope.$new(). 来完成
【解决方案2】:

稍微重组你的单元测试。我们有一个模式,其中控制器在 beforeEach() 中定义,因此它已准备好进行测试。您还需要导入您正在测试的控制器:

import ControllerToTest from 'path/to/your/real/controller';
describe('myApp.orders module',() => {
  let vm;
  beforeEach(() => {
    inject(($controller, $rootScope) => {
      vm = $controller(ControllerToTest,
        {
          $scope: $rootScope.$new()
        };
    });
  });

  describe('Order Controller', () => {
    it('should do something', () => {
      expect(vm).toBeDefined();
    });
  });
});

【讨论】:

    【解决方案3】:

    像这样改变你的控制器

       .controller('OrdersCtrl',['$scope', '$location', function($scope, $location) {
           $scope.changeView = function(view){
            $location.path(view); // path not hash
          }
        }]);
    

    【讨论】:

      猜你喜欢
      • 2014-12-22
      • 1970-01-01
      • 1970-01-01
      • 2016-05-09
      • 2015-08-27
      • 2013-10-19
      • 2017-04-03
      • 2015-08-12
      • 1970-01-01
      相关资源
      最近更新 更多