Javascript 不能更新茉莉花间谍
嗨,我有一个Angular服务,它使用另一个服务从init上的本地存储加载数据Javascript 不能更新茉莉花间谍,javascript,angularjs,testing,jasmine,Javascript,Angularjs,Testing,Jasmine,嗨,我有一个Angular服务,它使用另一个服务从init上的本地存储加载数据 angular .module('app') .factory('localStorage', function ($window) { if (!$window.localStorage) { // throw Error } return $window.localStorage; });
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'});
});
});
});
正如您在中看到的,应该返回用户数据部分。
我需要一种方法来更新容器
,以便getUser
返回预期的数据
我试图更新getItem
spy,但这不起作用。当我想要更改spy时,localStorageMock
已经被注入到会话
服务中
有什么帮助吗?最简单的方法是使用一个模拟值的变量,该值对于两个函数作用域都是通用的:
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
应该从beforeach
移动到it
(不涉及getItemValue
的规范可以使用更短的语法,it(“…”,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
spy值可以根据需要重新定义。简单的解决方案是完美的。谢谢如果你把答案改成ES5,你会得到一张赞成票。如果你是关于箭头函数的,它们在示例中的可读性很好,我用一个普通的替换了它。