无法找到变量:$ rootScope

时间:2016-02-02 13:05:06

标签: angularjs unit-testing karma-jasmine

我是单位测试的新手,即使我的测试是正确的,我也会收到这些错误,我只是无法弄清楚这些错误是什么意思,我尝试了几件事

 Can't find variable: $rootScope
 Error: Injector already created, can not register a module!

spec.js

   describe('test broadcast', function () {
    var $controller;

    beforeEach(function() {
        module('test');
        inject(function (_$rootScope_, _$controller_) {
            $rootScope = _$rootScope_;
            spyOn($rootScope, '$broadcast');

            // Notice how inject $controller here.
            $controller = _$controller_;
        });
    });

    it("should broadcast something", function ($rootScope) {
        $controller('myCtrl', {
            // Pass in the $rootScope dependency.
            $rootScope: $rootScope.$new()
        })
        // Here we actually run the controller.
        expect($rootScope.$broadcast).toHaveBeenCalledWith('update');
        //someObj = { data: testData};
        //expect($rootScope.$broadcast).toHaveBeenCalledWith('update', someObj);
    });
})

控制器

(function () {

    var test= angular.module('test');

    test.controller('myCtrl',
        function($rootScope, $scope, $resource, $location, $route, $routeParams, $log, catalogData) {

            $log.debug("myCtrl");
            $log.debug(myCtrl);

            $rootScope.$broadcast("update", {
                data: testData
            });
        }); // catalogCtrl
})();

2 个答案:

答案 0 :(得分:3)

您定义了一个名为rootScope的变量,而不是$rootScope - 更改您的定义:

rootScope.$apply();

虽然我个人喜欢这样定义它们:

var $rootScope;
beforeEach(inject(function(_$rootScope_) {
    $rootScope = _$rootScope_;
}));

答案 1 :(得分:1)

编辑2:

您无法访问$rootScope函数中的it,因为它不在当前的javascript scope中(不是有角度的$ scope,不要混淆)。

您需要在顶部与控制器一起定义它。

var $controller, $rootScope

从您的$rootScope功能中删除it,这样您就不会覆盖它。

// Notice there is no $rootScope parameter.
it("should broadcast something", function () {
    //Code
}

您还必须传入其他依赖项。 在与OP讨论之后,整个代码应如下所示:

describe('test broadcast', function () { 
    var $controller, $rootScope; 

    beforeEach(function() { 
        module('test'); 
        inject(function (_$rootScope_, _ $controller_) { 
        $rootScope = _$rootScope_; 
        spyOn($rootScope, '$broadcast'); 
        $controller = _$controller_; 
     }); 
}); 

it("should broadcast something", function () { 
    $controller('myCtrl', { 

        $scope: $rootScope.$new(), 

         catalogData: {} 
    }) 
    expect($rootScope.$broadcast).toHaveBeenCalledWith('update', {catalog:{}})}); 
})

编辑1:

您正在传递$scope依赖项。 $broadcast上会调用$rootScope,因此您需要将其传递出去。就像这样:

var testScope = $rootScope.$new()
$controller('myCtrl', {
    // Pass in the $rootScope dependency.
    $rootScope: testScope
}

原帖(如果它对任何人都有用)

您实际上并未在测试套件中的任何位置调用控制器。

你需要像

这样的东西
var $controller
beforeEach(inject(function (_$rootScope_, _$controller_) {
    $rootScope = _$rootScope_;
    spyOn($rootScope, '$broadcast'); 

    // Notice how inject $controller here.
    $controller = _$controller_;
}));

然后在测试中初始化它:

it("should broadcast something", function () {
    // Here we actually run the controller.
    $controller('myCtrl', {
        // Pass in the $rootScope dependency.
        $rootScope: $rootScope.$new()
    }
    expect($rootScope.$broadcast).toHaveBeenCalledWith('catalogUpdate');
    someObj = { catalog: catalogData};
    expect($rootScope.$broadcast).toHaveBeenCalledWith('catalogUpdate', someObj);
});  

这将删除有关$ rootScope.broadcast未被调用的错误。

看看"测试控制器"部分:https://docs.angularjs.org/guide/controller

至于无法注册模块,如果inject()之前有beforeEach(module('abc')),通常会发生这种情况。 如错误所示,在调用注入后,您无法注册另一个模块。