您好,我有一个Angular服务,它使用另一个服务从init上的本地存储加载数据。
angular
.module('app')
.factory('localStorage', function ($window)
{
if (!$window.localStorage)
{
// throw Error
}
return $window.localStorage;
});
angular
.module('app')
.factory('session', function (localStorage)
{
var container = JSON.parse(localStorage.getItem('sessionContainer'));
return {
getUser: getUser
};
});现在我想测试会话服务。
describe('SessionService', function ()
{
var service;
var localStorageMock;
// Load the module.
beforeEach(module('appRegistration'));
// Create mocks.
beforeEach(function ()
{
logMock = {};
localStorageMock = jasmine.createSpyObj('localStorageServiceMockSpy', ['setItem', 'getItem']);
localStorageMock.getItem.and.returnValue('{}');
module(function ($provide)
{
$provide.value('localStorage', localStorageMock);
});
inject(function (_session_)
{
service = _session_;
});
});
it('should call `getItem` on the `localStorageService` service', function ()
{
expect(localStorageMock.getItem).toHaveBeenCalledWith('sessionContainer');
});
describe('getUser method', function ()
{
it('should return an empty object when the user is not set', function ()
{
var result = service.getUser();
expect(result).toEqual({});
});
it('should return the user data', function ()
{
// localStorageMock.getItem.and.returnValue('{"user":{"some":"data"}}');
var result = service.getUser();
expect(result).toEqual({some: 'user data'});
});
});
});正如您在should return the user data部分中所看到的那样。我需要一种方法来更新container,以便getUser返回预期的数据。
我试着更新getItem间谍,但这不起作用。当我想要更改间谍时,localStorageMock已经注入到session服务中。
有什么帮助吗?
发布于 2016-09-19 04:46:46
最简单的方法是使用一个具有两个函数作用域通用的模拟值的变量:
var getItemValue;
beforeEach({
localStorage: {
getItem: jasmine.createSpy().and.callFake(function () {
return getItemValue;
}),
setItem: jasmine.createSpy()
}
});
...
it('should return the user data', function ()
{
getItemValue = '{"user":{"some":"data"}}';
inject(function (_session_) {
service = _session_;
});
var result = service.getUser();
expect(result).toEqual({some: 'user data'});
});请注意,对于所有规范,inject都应该从beforeEach迁移到it (不涉及getItemValue的规范可以使用更短的语法it('...', inject(function (session) { ... })))。
这揭示了服务设计中的缺陷,使得它不适合测试。
解决方案是让container进行懒惰的评估,这样在使用inject引导应用程序之后,就有时间模拟它了
.factory('session', function (localStorage)
{
var containerCache;
function getUser() {
...
return this.container;
}
return {
get container() {
return (containerCache === undefined)
? (containerCache = JSON.parse(localStorage.getItem('sessionContainer')))
: containerCache;
},
getUser: getUser
};
});此外,这也使得测试session.container成为可能。在这种情况下,无论何时需要,都可以重新定义localStorageMock.getItem侦探值。
https://stackoverflow.com/questions/39561921
复制相似问题