Javascript 角度单元测试:调用另一个控制器中定义的方法是抛出';未定义';这不是一个错误
我试图测试AngularJS文件,但它不能调用在另一个控制器中定义的方法 在MyPage文件中:Javascript 角度单元测试:调用另一个控制器中定义的方法是抛出';未定义';这不是一个错误,javascript,angularjs,jasmine,karma-runner,Javascript,Angularjs,Jasmine,Karma Runner,我试图测试AngularJS文件,但它不能调用在另一个控制器中定义的方法 在MyPage文件中: angular.module('MyApplication').controller('MyPageCtrl', function ($scope, $rootScope) { if($scope.pageChecker) { $scope.doSomething(); } } pageChecker()方法在App.js中的MyApplication controller中定义,
angular.module('MyApplication').controller('MyPageCtrl', function ($scope, $rootScope) {
if($scope.pageChecker) {
$scope.doSomething();
}
}
pageChecker()方法在App.js中的MyApplication controller中定义,并返回true或false
为了完整起见:
$scope.pageChecker = function() {
if(cookieCheck) {
return true;
}
else {
return false;
}
};
jasmine文件是:
describe("Page check", function(){
beforeEach(angular.mock.module('MyApplication'));
beforeEach(angular.mock.inject(function ($rootScope, $controller) {
var $scope = $rootScope.$new();
$controller('MyPageCtrl', { $scope: $scope});
}));
it("should call $scope.doSomething", function(){
spyOn($scope, "doSomething");
$scope.doSomething();
expect($scope.doSomething).toHaveBeenCalled();
});
});
我得到“TypeError:“undefined”不是函数(计算“$scope.pageChecker()”)
我想重写pageChecker方法以始终返回true。我该怎么做
编辑:多亏了Dskh,我有了我的答案,还有一个小改动:
describe("Page check", function(){
var $scope; //declare here, else it is a local variable inside the beforeEach
beforeEach(angular.mock.module('MyApplication'));
beforeEach(angular.mock.inject(function ($rootScope, $controller) {
$scope = $rootScope.$new();
// define the overriding methods here
$scope.pageChecker = function(){
return true;
};
// end overriding methods here
$controller('MyPageCtrl', { $scope: $scope});
}));
it("should call $scope.doSomething", function(){
spyOn($scope, "doSomething");
$scope.doSomething();
expect($scope.doSomething).toHaveBeenCalled();
});
});
在执行$rootScope.$new()时,您自己创建$scope,然后在使用$controller()方法时将其注入到您创建的控制器中 因此,如果希望该方法始终返回true,则只需自己创建该方法:
beforeEach(angular.mock.inject(function ($rootScope, $controller) {
var $scope = $rootScope.$new();
$scope.doSomething = function(){
return true;
};
$controller('MyPageCtrl', { $scope: $scope});
}));
还有一些解释:当你的应用程序真正运行时,$scope会被angular自动注入到你的控制器中。在你的测试中,你只是孤立地测试你的控制器,所以你需要自己创建scope对象并伪造你想要的任何行为。使用$rootScope()。$new()将为您提供$watch或$on等角度方法,但您需要自己重新创建自己的方法。我认为问题中有输入错误,我没有看到对$scope.pageChecker()的任何调用作为函数调用。看起来您的控制器调用$scope.pageChecker方法作为控制器实例化的一部分,当您在测试中在控制器创建中提供范围对象时,它确实没有pageChecker方法良好的catch,Eitan,但不是问题的原因。这是一个names-have-been-changed-to-protect-t他是我代码的无辜版本,因为我的雇主不希望我发布实际代码。:)谢谢你Dskh。这就成功了,因为我还发现我必须将$scope设置为全局变量。这阻止了我正确定义$scope,因为我将其定义为局部变量。噢!