如何检查实例化控制器中的函数是否可用以在 Jasmine 中进行单元测试
How to check if a function is available in instantiated controller for unit testing in Jasmine
我第一次尝试在 AngularJS 中对控制器进行单元测试。我想测试此控制器中的登录功能是否调用了正确的服务,但我收到错误消息,该功能在控制器中不存在。我做错了什么?我必须嘲笑更多吗?但是我不必模拟要测试的控制器中的功能,因为如果我这样做,整个测试将毫无意义,或者我错了吗?
控制器代码段:
function LoginController($scope, $state, myService, ngToast) {
$scope.loginUser = loginUser;
activate();
function activate() {}
function loginUser(credentials) {
myService.authenticate(/*things*/);
}
}
测试代码:
describe('Login Controller', function () {
'use strict';
//globals
var controller, scope;
var $controller, $state, myService, ngToast;
//needed modules
beforeEach(module('app.login'));
beforeEach(module('app.core'));
beforeEach(module('ui.router'));
//instanciate Controller
beforeEach(inject(function (_$controller_, _$state_, _myService_, _ngToast_) {
scope = {};
$state = _$state_;
myService = _myService_;
ngToast = _ngToast_;
$controller = _$controller_;
controller = $controller('LoginCtrl', {
$scope: scope,
$state: $state,
myService: myService,
ngToast: ngToast
});
}));
it('should have an existing controller', function () {
expect(controller).toBeDefined();
});
/*************************** unit-tests ***************************/
describe('.loginUser()', function () {
it('should exist', function () {
expect(controller.loginUser).toBeDefined();
});
});
});
运行 karma 开始时出现的错误:
.loginUser()
✗ should exist
TypeError: controller.loginUser is not a function
at Object.<anonymous> (src/login/login.controller.spec.js:74:31)
但在我看来控制器确实存在,因为这个测试没有失败:
Login Controller
✓ should have an existing controller
这是因为 loginUser 是在 $scope 而不是控制器上定义的,所以 loginUser 没有绑定到您测试中的控制器对象。
要测试登录用户,请执行以下操作:
- 在你的 beforeEach 中注入 $rootScope
- 设置范围 = $rootScope.$new()
- 应使用此范围创建控制器
你的测试应该检查 loginUser 是否定义在范围内
describe('Login Controller', function () {
'use strict';
//globals
var controller, scope;
var $controller, $state, myService, ngToast;
//needed modules
beforeEach(module('app.login'));
beforeEach(module('app.core'));
beforeEach(module('ui.router'));
//instanciate Controller
beforeEach(inject(function (_$controller_, _$state_, _myService_, _ngToast_, _$rootScope_) {
scope = _$rootScope_.$new();
$state = _$state_;
myService = _myService_;
ngToast = _ngToast_;
$controller = _$controller_;
controller = $controller('LoginCtrl', {
$scope: scope,
$state: $state,
myService: myService,
ngToast: ngToast
});
}));
it('should have an existing controller', function () {
expect(controller).toBeDefined();
});
/*************************** unit-tests ***************************/
describe('.loginUser()', function () {
it('should exist', function () {
expect(scope.loginUser).toBeDefined();
});
});
});
如果您想在控制器本身上测试 loginUser,则使用控制器作为语法,您可以在其中设置 this.loginUser = loginUser 而不是 $scope.loginUser = loginUser。然后你就可以在你的测试中使用controller.loginUser。
我第一次尝试在 AngularJS 中对控制器进行单元测试。我想测试此控制器中的登录功能是否调用了正确的服务,但我收到错误消息,该功能在控制器中不存在。我做错了什么?我必须嘲笑更多吗?但是我不必模拟要测试的控制器中的功能,因为如果我这样做,整个测试将毫无意义,或者我错了吗?
控制器代码段:
function LoginController($scope, $state, myService, ngToast) {
$scope.loginUser = loginUser;
activate();
function activate() {}
function loginUser(credentials) {
myService.authenticate(/*things*/);
}
}
测试代码:
describe('Login Controller', function () {
'use strict';
//globals
var controller, scope;
var $controller, $state, myService, ngToast;
//needed modules
beforeEach(module('app.login'));
beforeEach(module('app.core'));
beforeEach(module('ui.router'));
//instanciate Controller
beforeEach(inject(function (_$controller_, _$state_, _myService_, _ngToast_) {
scope = {};
$state = _$state_;
myService = _myService_;
ngToast = _ngToast_;
$controller = _$controller_;
controller = $controller('LoginCtrl', {
$scope: scope,
$state: $state,
myService: myService,
ngToast: ngToast
});
}));
it('should have an existing controller', function () {
expect(controller).toBeDefined();
});
/*************************** unit-tests ***************************/
describe('.loginUser()', function () {
it('should exist', function () {
expect(controller.loginUser).toBeDefined();
});
});
});
运行 karma 开始时出现的错误:
.loginUser()
✗ should exist
TypeError: controller.loginUser is not a function
at Object.<anonymous> (src/login/login.controller.spec.js:74:31)
但在我看来控制器确实存在,因为这个测试没有失败:
Login Controller
✓ should have an existing controller
这是因为 loginUser 是在 $scope 而不是控制器上定义的,所以 loginUser 没有绑定到您测试中的控制器对象。
要测试登录用户,请执行以下操作:
- 在你的 beforeEach 中注入 $rootScope
- 设置范围 = $rootScope.$new()
- 应使用此范围创建控制器
你的测试应该检查 loginUser 是否定义在范围内
describe('Login Controller', function () { 'use strict'; //globals var controller, scope; var $controller, $state, myService, ngToast; //needed modules beforeEach(module('app.login')); beforeEach(module('app.core')); beforeEach(module('ui.router')); //instanciate Controller beforeEach(inject(function (_$controller_, _$state_, _myService_, _ngToast_, _$rootScope_) { scope = _$rootScope_.$new(); $state = _$state_; myService = _myService_; ngToast = _ngToast_; $controller = _$controller_; controller = $controller('LoginCtrl', { $scope: scope, $state: $state, myService: myService, ngToast: ngToast }); })); it('should have an existing controller', function () { expect(controller).toBeDefined(); }); /*************************** unit-tests ***************************/ describe('.loginUser()', function () { it('should exist', function () { expect(scope.loginUser).toBeDefined(); }); }); });
如果您想在控制器本身上测试 loginUser,则使用控制器作为语法,您可以在其中设置 this.loginUser = loginUser 而不是 $scope.loginUser = loginUser。然后你就可以在你的测试中使用controller.loginUser。