我希望单元测试(karma)一个指令,它有一个带有注入服务的控制器。
请参阅以下代码:
angular
.module('webkr')
.directive('userChangePassword', userChangePassword)
.directive('compareTo', compareTo);
/** @ngInject */
function userChangePassword() {
var directive = {
restrict: 'E',
scope: {},
templateUrl: 'app/components/account/user_change_password/user_change_password.html',
controller: changePasswordController,
controllerAs: 'vm',
bindToController: true
};
return directive;
/** @ngInject */
function changePasswordController($log, User, toastr) {
var _this = this;
//properties
_this.formModel = {
password: null,
oldPassword: null,
passwordRepetition: null
};
_this.formDefinition = {
oldPassword: {
name: 'oldPassword',
label: 'Altes Passwort',
placeholder: 'Altes Passwort',
error: 'old password is required.'
},
password: {
name: 'password',
label: 'Neues Passwort',
placeholder: 'Neues Passwort',
error: 'new password is required.'
},
passwordRepetition: {
name: 'passwordRepetition',
label: 'Passwort bestätigen',
placeholder: 'Passwort bestätigen',
errorRequired: 'old password is required.',
errorInvalid: 'Confirmation password is not equal new password.'
}
};
//methods
/**
* cancel change password procedure
*/
_this.cancelChangePassword = function () {
//clean form data
_this.changePasswordForm.$setPristine();
};
/**
* submit change password
*/
_this.submitPasswordChange = function () {
if (_this.changePasswordForm.$invalid) {
return;
}
User.changePassword(_this.formModel).then(function () {
toastr.info('Password changed', JSON.stringify(_this.formModel));
_this.cancelChangePassword();
}, function (err) {
toastr.error('Can`t change password');
$log.error(err);
});
};
}
}
我的单元测试相应:
(function () {
'use strict';
describe('directive user_change_password', function () {
var el, compile, rootScope, controller, mockUserService;
beforeEach(function () {
mockUserService = jasmine.createSpyObj('User', ['changePassword'])
module('webkr', 'ngMockE2E')
});
beforeEach(inject(function ($compile, $rootScope, $controller, $q, $log, toastr) {
compile = $compile;
rootScope = $rootScope;
//Service routes used in controller
mockUserService.changePassword.and.returnValue($q.when("result"));
//Compile element
el = compile("<user-change-password></user-change-password>")(rootScope);
rootScope.$digest();
//Init controller
controller = el.controller("userChangePassword", {
$log: $log,
User: mockUserService,
toastr: toastr
});
//Spy on the form
spyOn(controller.changePasswordForm, '$setPristine')
}));
it('should be compiled', function () {
expect(el.html()).not.toEqual(null);
});
});
})();
不知何故,控制器未正确初始化。当我删除对象({$log:$log,User:mockUserService,toastr:toastr}
)时,一切正常。我在这里做错了什么?
答案 0 :(得分:1)
模拟控制器依赖项适用于涉及$controller
的仅限控制器的规范。
el.controller
是getter方法,has only 1 parameter:
controller(name) - 检索当前元素的控制器或 它的父母。
此刻
//Init controller
controller = el.controller("userChangePassword", { ... });
编译指令并对其控制器进行实例化,这就是为什么可以检索它的实例。
当测试指令控制器坚持在注射器级别进行模拟时,模拟服务:
beforeEach(module('webkr', 'ngMockE2E', function ($provide) {
$provide.factory('User', function ($q) {
return { changePassword: jasmine.createSpy().and.returnValue($q.when("result")) };
});
}));