在使用Jasmine测试Angular控制器时出现未知提供程序:$scopeProvider问题

4

我正在尝试使用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();
    });
});

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


1
你看过这个线程吗?https://dev59.com/0obca4cB1Zd3GeqPYqqV?它有帮助吗?谢谢。 - alecxe
是的,我已经看到了。我不明白他们在做什么不同的事情。 - MadPhysicist
2个回答

3

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

在单元测试中,由于没有存在的服务,您无法注入$scope。但是有一个$rootScope提供程序,其中包含像$new这样的API,可以创建一个新的子级范围。

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

由于您无法注入$scope,因此出现(no such provider exists to provide you $scope)的错误提示。

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

在你提供的答案中,
 beforeEach(inject(function(_$controller_, _$rootScope_) {
   $controller = _$controller_;
   $rootScope = _$rootScope_;
   HomeCtrl = $controller('HomeCtrl', {
    $scope: $rootScope,
   });
  }));

您正在注入$rootScope并直接将其传递给HomeCtrl。 这样是可以的,但在执行测试时,会将控制器代码中的所有变量和函数添加到$rootScope中。
但在实际情况中,您的HomeCtrl需要一个$scope(子作用域)。因此,为了复制实际情况,最好传递一个子作用域。
beforeEach(inject(function(_$controller_, _$rootScope_) {
  $controller = _$controller_;
  $scope = _$rootScope_.$new();
  HomeCtrl = $controller('HomeCtrl', {
   $scope: $scope,
  });
 }));

谢谢。这很有教育意义和帮助! - MadPhysicist

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();
    }));
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接