2016-09-18 6 views
1

Привет У меня есть служба углов, которая использует другую службу, которая загружает данные из локального хранилища в init.cant update jasmine spy

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, когда я хочу изменить шпиона.

Любая помощь?

ответ

2

Самый простой способ, чтобы иметь переменную издевались значение, которое является общим для обеих функциональных областей:

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 для всех спецификаций (спецификации, что дон» t include 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 может быть переопределено в случае необходимости.

+0

Простое решение идеально. Благодарю. Вы получите голосование, если вы измените свой ответ на ES5 – WitteStier

+0

Если вы используете функцию стрелки, они хороши в примерах для их удобочитаемости, я заменил ее на обычную. – estus

Смежные вопросы