我正在练习Angular和自动化测试。
我制作了一个简单的应用来告诉用户他们的密码强度。最初一切都在PasswordController中并使用了$ scope。然后我将逻辑移动到服务中。控制器和服务目前是:
myApp.controller("PasswordController", function ($scope, PasswordService) {
$scope.users = PasswordService.list();
$scope.saveUser = function () {
PasswordService.save($scope.newUser);
$scope.newUser = {};
}
$scope.delete = function (id) {
PasswordService.delete(id);
if($scope.newUser.id == id){
$scope.newUser = {};
}
}
$scope.edit = function(id) {
$scope.newUser = angular.copy(PasswordService.get(id));
}
});
myApp.service('PasswordService', function() {
//user with unique id
var uid = 1;
//user array
var users = [
{
id: 0,
'name': 'a_test_name',
'password': 'a_test_pw',
'pwStrength': 'medium'
}
];
this.save = function(user) {
if (user.id == null) {
user.id = uid++;
this.grade(user);
users.push(user);
}
else {
for (i in users) {
if (users[i].id == user.id) {
users[i] = user;
this.grade(user);
}
}
}
}
this.get = function(id) {
for (i in users) {
if (users[i].id == id) {
return users[i];
}
}
}
this.delete = function(id) {
for (i in users) {
if (users[i].id == id) {
users.splice(i, 1);
}
}
}
this.list = function () {
return users;
}
this.grade = function(user) {
var size = user.password.length;
if (size > 8) {
user.pwStrength = "strong";
}
else if (size > 3) {
user.pwStrength = "medium";
}
else {
user.pwStrength = "weak";
}
}
});
当所有内容都在PasswordController中时,我的测试用例一直在工作,但我无法弄清楚如何设置测试用例以使用该服务。这是没有修改的测试代码:(因此一些变量名称不完全对齐)
describe('PasswordController', function() {
beforeEach(module('myApp'));
var $controller;
var $scope;
var controller;
beforeEach(inject(function(_$controller_){
// The injector unwraps the underscores (_) from around the parameter names when matching
$controller = _$controller_;
}));
describe("$scope.grade", function() {
beforeEach(function() {
$scope = {};
controller = $controller("PasswordController", { $scope: $scope });
});
it("method should exist", function() {
expect($scope.grade).toBeDefined();
});
it('sets the strength to "strong" if the password length is >8 chars', function() {
$scope.password = 'longerthaneightchars';
$scope.grade();
expect($scope.strength).toEqual('strong');
});
it('strength to "medium" if the password length is >8 chars && <3 chars', function() {
$scope.password = 'between';
$scope.grade();
expect($scope.strength).toEqual('medium');
});
it('sets the strength to "weak" if the password length <3 chars', function() {
$scope.password = 'a';
$scope.grade();
expect($scope.strength).toEqual('weak');
});
});
});
我无法弄清楚如何将测试用例转换为使用PasswordService。我试图将PasswordService注入控制器并尝试使用spyOn来模拟服务并以这种方式使用它,但到目前为止还没有运气。
beforeEach(module('myApp', function ($provide) {
PasswordService = jasmine.createSpyObj("PasswordService", ["save" ...]);
controller = $controller("PasswordController", { $scope: $scope, PasswordSerice: PasswordService });
赞赏任何教程链接的提示。非常感谢。
答案 0 :(得分:1)
由于你将控制器和服务分开(这可能是一件好事),现在分开测试也是有意义的。
您应该为控制器创建一个测试。测试仅针对控制器内部的方法(保存,删除和编辑)。
然后,您将为服务创建另一个测试,该测试将涵盖服务中的方法。
我将为这两种方案创建一个示例示例来帮助您:
describe('PasswordController Specification', function() {
beforeEach(module('myApp'));
var myPasswordController;
beforeEach(inject(function(_$controller_, $rootScope){
myPasswordController= _$controller_('PasswordController', {
$scope: $rootScope.$new();
});
}));
it("Should save the user", inject(function(PasswordService) {
//setup
var myFakeUser = {id: 1, name: 'whatever'};
myPasswordController.newUser = myFakeUser;
/*
Here I am spying the save method. This is necessary to check if it was
called. It will actually replace the original implementation with a
mocked empty function. And this is right because the controller
shouldn't if the service is doing what is supposed to. This is up for
the service test.
*/
spyOn(PasswordService, 'save');
//action
myPasswordController.saveUser(myMockedUser);
//assertion
expect(PasswordService.save).toHaveBeenCalled();
expect(myPasswordController.newUser).toBe({});
}));
});
服务测试:
describe('PasswordService Specification', function() {
beforeEach(module('myApp'));
var myPasswordService;
beforeEach(inject(function(PasswordService){
myPasswordService = PasswordService;
}));
it("Should save new user", inject(function() {
//setup
var numberOfUsers= myPasswordService.list().length;
var newUser = {
'name': 'a_test_name',
'password': 'a_test_pw',
'pwStrength': 'medium'
}
/*
Here I am spying the grade method. This is necessary to check if it was
called. It will actually replace the original implementation with a
mocked empty function. And this is right because we are only concerned
about the save method now.
*/
spyOn(myPasswordService, 'grade');
//action
myPasswordService.save(newUser);
//assertion
expect(myPasswordService.grade).toHaveBeenCalled();
expect(myPasswordService.list().length).toBe(numberOfUsers + 1);
}));
});
您还可以测试其他一些内容,但我希望这能为您提供开始工作的洞察力