簡體   English   中英

無法更新茉莉花間諜

[英]cant update jasmine spy

嗨我有一個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服務。

有幫助嗎?

最簡單的方法是使用一個具有模擬值的變量,這對於兩個函數作用域都是通用的:

    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'});
        });

請注意,對於所有規范,應將injectbeforeEach移動到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 spy值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM