Testing Ionic Storage with Jasmine

Hi all,

Im currently in the proces of unit testing my ionic angular application (ionic 6). However im running into issues when I try to mock the ionic storage. I’m not sure what i’m doing wrong, since mocking like this works for other services but does not seem to work for @ionic/storage-angular.

Code example:

import { Storage } from '@ionic/storage-angular';

describe('StorageService', () => {
    let service: StorageService;
    let angularStorageSpy: jasmine.SpyObj<Storage>;
  
    beforeEach(() => {
      const spyStorage = jasmine.createSpyObj('Storage', ['create', 'get', 'set']);
  
      TestBed.configureTestingModule({
        imports: [],
        providers: [
          {
            provide: Storage,
            useValue: spyStorage
          }
        ]
      });
      service = TestBed.inject(StorageService);
      angularStorageSpy = TestBed.inject(Storage) as jasmine.SpyObj<Storage>;
    });
  
    it('should get an item from storage', async () => {
      const key = 'test';
      const stubValue = 'As2342fAfgsdr';
  
      angularStorageSpy.get.and.returnValue(Promise.resolve(stubValue));
  
      const response: string = await service.get(key);
  
      expect(angularStorageSpy.get.calls.count())
        .withContext('spy method was called once')
        .toBe(1);
  
      expect(response)
        .withContext('response was same as stubValue')
        .toBe(stubValue);
    });
  });
  

The above code basically tests a general get request on the storage service. The function nothing special but for context the code is this:

export class StorageService {
    #storage: Storage | null = null;
  
    constructor(private storage: Storage) {
      this.init();
    }
  
    async init() {
      const storage = await this.storage.create();
      this.#storage = storage;
    }
  
    //Get existing key from storage
    public get(key: string): Promise<any> {
      return this.#storage?.get(key);
    }
}

When running this test I would expect that the get function of ionic storage is being called. However, it is not. Basically both expect statements fail with the following errors:

  • spy method was called once: Expected 0 to be 1.
  • response was same as stubValue: Expected undefined to be ‘As2342fAfgsdr’.

What am I doing wrong here?

Hi, I’m in a pretty similar situation. Could you finally resolve it. If you did, could you share how, please?

I wish I had the answer but i’ve skipped this for now.

I’m not sure if it’s a bug within ionic-angular of if im just using a wrong implementation.

It is because of the ? on storage. _storage is null in the test so will not run the get.

I think in the test you would have to run init to set _storage as a storage object. I am not sure how to mock that storage object.

just mock your service like that
const mockedStorageService = jasmine.createSpyObj(‘StorageService’, [‘get’]);
in the providers add : { provide: StorageService, useValue: mockedStorageService },
and inside beforeach add for example (it must return a promise with your values
mockedStorageService.get.and.returnValue(Promise.resolve(stubValues));