首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法更新jasmine spy

无法更新jasmine spy
EN

Stack Overflow用户
提问于 2016-09-19 03:43:42
回答 1查看 383关注 0票数 1

您好,我有一个Angular服务,它使用另一个服务从init上的本地存储加载数据。

代码语言:javascript
复制
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
        };
    });

现在我想测试会话服务。

代码语言:javascript
复制
    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服务中。

有什么帮助吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-09-19 04:46:46

最简单的方法是使用一个具有两个函数作用域通用的模拟值的变量:

代码语言:javascript
复制
    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引导应用程序之后,就有时间模拟它了

代码语言:javascript
复制
.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侦探值。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39561921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档