我想测试一个 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 thedescribe()
method, so it's available only within that function or to any child functions defined inside this function.
describe()
之外的任何函数(例如 Main JS 中的事件处理程序 ($on))都不会知道它的存在。这就是调用该处理程序时出现错误的原因。
您可以通过两种方式正确初始化 Main
来解决此问题。
- 您可以在注册事件处理程序之前执行此操作,或者在 Controller 内创建 Angular 模块(或)之前。
- 您可以在同一模块中将
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/