未知提供者:使用Jasmine测试角度控制器时的$ scopeProvider

时间:2016-10-01 23:39:43

标签: javascript angularjs jasmine karma-jasmine

我正在尝试使用Jasmine和Karma为Web应用程序的特定控制器实现单元测试。目前它发出以下错误:

Chrome 53.0.2785 (Mac OS X 10.10.5) HomeCtrl should be defined FAILED
  Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope
  http://errors.angularjs.org/1.5.5/$injector/unpr?p0=%24scopeProvider%20%3C-%20%24scope

以下是测试文件的代码:

describe('HomeCtrl', function(){
    var $controller, HomeCtrl;

    beforeEach(angular.mock.module('TestModule'));

    beforeEach(inject(function(_$controller_, _$rootScope_, _$scope_) {
        $controller = _$controller_;
        rootScope = $rootScope.new();
        scope = $scope.new();
        HomeController = $controller('HomeCtrl', {
                $scope: scope
        });
    }));

    // Verify our controller exists
    it('should be defined', function() {
        expect(HomeController).toBeDefined();
    });
});

有人能告诉我我做错了吗?

2 个答案:

答案 0 :(得分:2)

在AngularJS中,所有范围都是$rootScope的子项。

在单元测试中,您无法注入 $scope,因为没有服务存在。但是有一个$rootScope提供程序包含API,例如$new来创建新的子范围。

$rootScope.$new(),创建一个新的子范围。

因为,你不能注入 $scope(没有这样的提供者为你提供$scope

Error: [$injector:unpr] Unknown provider: $scopeProvider <- $scope

在答案中,您提供了

 beforeEach(inject(function(_$controller_, _$rootScope_) {
   $controller = _$controller_;
   $rootScope = _$rootScope_;
   HomeCtrl = $controller('HomeCtrl', {
    $scope: $rootScope,
   });
  }));

您正在注射$rootScope并直接将$rootScope传递给HomeCtrl。它可以工作,但在执行测试时,它会将控制器代码中的所有变量和函数添加到$rootScope

但在实际情况中,您的HomeCtrl期待$scope(子范围)。因此,为了复制实际场景,如果传递子范围会更好。

beforeEach(inject(function(_$controller_, _$rootScope_) {
  $controller = _$controller_;
  $scope = _$rootScope_.$new();
  HomeCtrl = $controller('HomeCtrl', {
   $scope: $scope,
  });
 }));

答案 1 :(得分:1)

以下代码成功:

describe('HomeCtrl', function(){
    var $controller, HomeCtrl;
    var $rootScope, $scope;

    beforeEach(angular.mock.module('TestModule'));

    beforeEach(inject(function(_$controller_, _$rootScope_) {
        $controller = _$controller_;
        $rootScope = _$rootScope_;
        HomeCtrl = $controller('HomeCtrl', {
                $scope: $rootScope,
        });
    }));

    // Verify our controller exists
    it('should be defined', inject(function($controller) {
        expect(HomeCtrl).toBeDefined();
    }));
});