javascript - 尽管变量在范围内,但 Jasmine 测试用例中 undefined variable

标签 javascript angularjs unit-testing scope jasmine

我想测试一个 Controller ,它监听事件来执行一些操作。事件处理程序依赖于名为 Main全局变量。我试图通过模拟所有依赖项来对事件监听器进行单元测试,但 Karma 抛出错误:

ReferenceError:Main 未定义

Angular 代码:

App.controller('AppController', ['$scope', function($scope){
    $scope.$on('$viewContentLoaded', function() {
        Main.initComponents(); // init core components
    });
}]);

规范文件:

describe("App", function () {
    var scope, AppController, Main;
    describe("Login", function () {
        beforeEach(module("App"));
        beforeEach(inject(['$rootScope', '$controller', function($rootScope, $controller){
            scope = $rootScope.$new();
            Main = jasmine.createSpyObj("Main",["initComponents"]);
            AppController = $controller('AppController', {$scope : scope});
        }]));
        it("should call initComponents() on Main module on $viewContentLoaded event", inject(['$rootScope', function ($rootScope) {
            $rootScope.$broadcast('$viewContentLoaded');
            expect(Main.initComponents).toHaveBeenCalled();
        }]));
    });
});

karma.conf.js:

module.exports = function(config){
    config.set({

        basePath : './',

        files : [
            'app/bower_components/angular/angular.js',
            'app/bower_components/oclazyload/dist/oclazyLoad.min.js',
            'app/bower_components/angular-ui-router/release/angular-ui-router.min.js',
            'app/bower_components/angular-mocks/angular-mocks.js',
            'app/**/app.js',
            'app/**/controllers.js',
            'app/**/services.js',
            'app/**/directives.js',
            'app/**/filters.js',
            'app/**/routes.js',
            'app/**/specs.js'
        ],

        autoWatch : true,

        frameworks: ['jasmine'],

        browsers : ['Chrome'],

        plugins : [
            'karma-chrome-launcher',
            'karma-firefox-launcher',
            'karma-jasmine',
            'karma-junit-reporter'
        ],

        junitReporter : {
            outputFile: 'test_out/unit.xml',
            suite: 'unit'
        }

    });
};

有什么问题吗?感谢您的帮助。

最佳答案

由于定义这些变量的范围,这是一个变量可见性问题。

要使您的 $viewContentLoaded 处理程序正常工作,它需要一个 NOT 在当前范围或任何范围中定义的 Main 对象。作用域链中的父作用域。您使用 createSpyObj 创建的 Main 模拟对象位于使用 describe() 定义的 App 测试套件的范围内>。如果你看看你的代码,

describe("App", function () {
    var scope, AppController, Main; 
    /* remaining code */
}

As you can see above, Main is a local variable defined in the describe() method, so it's available only within that function or to any child functions defined inside this function.

describe() 之外的任何函数(例如 Main JS 中的事件处理程序 ($on))都不会知道它的存在。这就是调用该处理程序时出现错误的原因。

您可以通过两种方式正确初始化 Main 来解决此问题。

  1. 您可以在注册事件处理程序之前执行此操作,或者在 Controller 内创建 Angular 模块(或)之前。
  2. 您可以在同一模块中将 Main 设为 Angular 服务,并将其注入(inject)到 您的 Controller 如下所示。

主要 JS

 App.service('Main', function(){

 });

 App.controller('AppController', ['$scope', 'Main', function($scope, Main){
        $scope.$on('$viewContentLoaded', function() {
            Main.initComponents(); // init core components
        });
 }]);

关于javascript - 尽管变量在范围内,但 Jasmine 测试用例中 undefined variable ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33011347/

相关文章:

javascript - JavaScript :void mean? 是什么意思

javascript - 带有 ng-repeat 表的嵌套数组

javascript - Angular 1.2.5 嵌套动画

c# - VS2010 Ultimate 中缺少测试设置模板

java - 使用 Jersey2.0 访问 JerseyTest 中的 springbean

performance - 如何加快 grails 测试执行速度

javascript - 尝试获取json对象的值

javascript - tone.js:如何知道 triggerRelease 何时完成

javascript - 如何将模块作为依赖注入(inject)添加到 AngularJS 中的其他抛出代码中?

javascript - 如何在 AngularJS 中使用 ng-repeat 插入 html 代码?