我正在使用AngularJs 1.4.4编写应用程序,并且刚刚首次开始使用TDD。我使用Karma和Jasmine并且在$ scope上测试表达式时没有遇到任何问题,但是当我尝试使用'这个'在Controller中,它返回undefined。 Angular表示使用' this'在您的控制器中是最佳实践,但我没有找到明确的测试示例。
这是我的控制器
'user_strict';
var app = angular.module('app', ['ngRoute', 'ngAnimate']);
angular.module('app')
app.controller('LoginCtrl', ['$scope', function($scope) {
var login = this;
login.user = {message:'hello'};
$scope.userName = "Anthony";
}])

我的测试脚本
'use strict';
describe('Controller: LoginCtrl', function() {
// load the controller's module
beforeEach(module('app'));
var LoginCtrl,
scope;
// initalize the controller and a mock scope
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
LoginCtrl = $controller('LoginCtrl', {
$scope: scope,
});
}));
it('should equal to equal to Anthony', function() {
expect(scope.userName).toBe("Anthony");
});
it('login user should equal to hello', function() {
expect(login.user.message).toBe('hello');
})
});

第一次测试通过,但第二次返回此错误/失败;
控制器:LoginCtrl登录用户应该等于hello FAILED
TypeError:' undefined'不是对象(评估' login.user.message')
我的假设是,它需要像控制器和范围一样注入,但我尝试过的方法并没有奏效。非常感谢任何帮助:)
答案 0 :(得分:2)
在控制器中使用this
是一个所谓的"控制器作为" 模式,在official docs中简要描述。
考虑以下代码:
app.controller('LoginCtrl', ['$scope', function($scope) {
var login = this;
login.user = {message:'hello'};
$scope.userName = "Anthony";
}]);
这里,function ($scope) { ... }
是您的控制器的构造函数,this
是对象的构造函数引用,它将在执行构造函数时创建。该对象将使用this
保存您为其提供的所有内容。使用代码
LoginCtrl = $controller('LoginCtrl', { $scope: scope });
变量LoginCtrl
包含该构造对象。您可以通过this
变量引用其LoginCtrl
分配的属性。所以基本上你的测试应该改为:
it('login user should equal to hello', function() {
expect(LoginCtrl.user.message).toBe('hello');
})
致Q / A accessing $scope from unit test file when using the vm "ControllerAs" syntax from AngularJS HotTowel的信用,您可在其中找到更多信息。
答案 1 :(得分:1)
var login = this;
在JavaScript变量中,函数作用域是本地的。它们不能在函数外部访问。
你正在尝试做同样的事情。你得到TypeError undefined
的方式。
以这种方式做到。
$scope.login = this;
$scope.login.user = {message:'hello'};
此login
可通过$scope