我有一个angularjs服务,它使用角度值来存储用户名。
(function() {
'use strict';
angular.module('myapp.services', [])
.service('authService', AuthService)
.value('authStore', {
username: null
});
AuthService.$inject = ['authStore'];
function AuthService(authStore) {
var svc = this;
var _username = authStore.username;
svc.isLoggedIn = IsLoggedIn;
svc.logout = Logout;
svc.login = Login;
svc.getUsername = GetUsername;
function IsLoggedIn() {
return _username != null && _username && _username != '';
}
function Logout() {
authStore.username = null;
_username = null;
}
function GetUsername() {
return _username;
}
function Login(username) {
authStore.username = username;
_username = username;
}
}
})();
我正在使用jasmine来测试我的isLoggedin方法。 所以我的测试会是;
(function () {
'use strict'
describe('Auth Service Tests', function () {
beforeEach(module('ionic'));
beforeEach(module('myapp.services'));
var provider
var authStore;
var authService;
beforeEach(function () {
module(function ($provide) {
authStore = {
username: null
};
$provide.value('authStore', authStore);
});
});
beforeEach(inject(function (_authService_) {
authService = _authService_;
}));
describe('isLoggedIn', function () {
it('should be false the username is null.', function () {
spyOn(authStore, 'username').and.returnValue(null);
expect(authService.isLoggedIn()).toBe(false); //success
//(this is because the authStore is initialized with username: null, not because of the spyOn line above)
console.log(authService.getUsername()); //null
});
it('should be true the username has a value', function () {
spyOn(authStore, 'username').and.returnValue('test');
expect(authService.isLoggedIn()).toBe(true); //Failed
console.log(authService.getUsername()); //null
});
});
});
})();
我遇到的问题是。我无法在authStore中更改用户名的返回值。它总是返回我在beforeEach中设置的模拟值。
1)我在这里错过了什么吗?
2)什么是模拟在测试中使用的angularjs值的正确方法。在这样的场景中,需要将其从测试更改为测试???
答案 0 :(得分:0)
首先,您正在尝试监视字符串类型(authStore.username
)的字段。这是不可能的。字符串不是函数。它无法返回任何东西。只有一个价值。间谍用于替换另一个伪造的功能。不要改变字符串的值。
但这无论如何都是必要的:因为它只是一个字符串,所以没有什么可以窥探的。只需设置您希望拥有的值即可。您甚至不需要提供虚假的实现,因为虚假实现与真实实现相同:
(function () {
'use strict'
describe('Auth Service Tests', function () {
beforeEach(module('ionic', 'myapp.services'));
var authStore;
var authService;
beforeEach(inject(function (_authService_, _authStore_) {
authService = _authService_;
authStore = _authStore_;
}));
describe('isLoggedIn', function () {
it('should be false the username is null.', function () {
authStore.username = null;
expect(authService.isLoggedIn()).toBe(false);
console.log(authService.getUsername());
});
it('should be true the username has a value', function () {
authStore.username = 'test';
expect(authService.isLoggedIn()).toBe(true);
console.log(authService.getUsername());
});
});
});
})();
答案 1 :(得分:0)
我在@JD Nizet的回答的帮助下解决了这个问题。在这里发布,因为对于遇到同样问题的人来说,这可能是一个学习点。
第一关,@JD Nizet提供的解决方案无效,原因是我的服务设计不佳。
我应该将完整的authStore存储为服务中的私有变量而不仅仅是用户名。
var _username = authStore.username;
应该改为
var _authStore = authStore;
然后我必须更新我的方法以使用新的_authStore并且测试工作! 这是改变的完整服务;
(function() {
'use strict';
angular.module('myapp.services', [])
.service('authService', AuthService)
.value('authStore', {
username: null
});
AuthService.$inject = ['authStore'];
function AuthService(authStore) {
var svc = this;
var _authStore = authStore;
svc.isLoggedIn = IsLoggedIn;
svc.logout = Logout;
svc.login = Login;
svc.getUsername = GetUsername;
function IsLoggedIn() {
return _authStore.username != null && _authStore.username && _authStore.username != '';
}
function Logout() {
_authStore.username = null;
}
function GetUsername() {
return _authStore.username;
}
function Login(username) {
_authStore.username = username;
}
}
})();