簡體   English   中英

離子存儲 v3 - 單元測試 | 類型錯誤:_this.storage.forEach 不是 function

[英]Ionic Storage v3 - Unit Tests | TypeError: _this.storage.forEach is not a function

我有一個用於@ionic/storage-angularStorageService包裝器,其中我有一個 function,大致如下所示:

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

@Injectable({
  providedIn: 'root'
})
export class StorageService {
  constructor(public storage: Storage) {}

  async getData() {
    const data = [];
    await this.initStorage();

    return new Promise((resolve) => {
      this.storage
        .forEach((value, key) => {
          if (key.startsWith('data-')) {
            data.push({
              key: 'someKey,
              value,
            });
          }
        })
        .then(() => resolve(data));
    });
  }

  // other functions here
}

我有一個看起來像這樣的單元測試

import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { fakeAsync, flush, TestBed } from '@angular/core/testing';
import { StorageService } from './storage.service';
import { Storage } from '@ionic/storage-angular';


describe('StorageService', () => {
  let service: StorageService;
  let mockStorage: jasmine.SpyObj<Storage>;

  beforeEach(() => {
    mockStorage = jasmine.createSpyObj('Storage', ['get', 'set', 'remove', 'create']);

    TestBed.configureTestingModule({
      schemas: [CUSTOM_ELEMENTS_SCHEMA],
      providers: [
        { provide: Storage, useValue: mockStorage },
      ],
    });
    service = TestBed.inject(StorageService);
  });

  describe('getData()', () => {
    it('should call StorageService.initStorage()', fakeAsync(() => {
      spyOn<any>(service, 'initStorage').and.stub();

      service.getData();
      flush();

      expect(service['initStorage']).toHaveBeenCalled();
    }));
  });

  // other tests here
});

它失敗了

Error: Uncaught (in promise): TypeError: _this.storage.forEach is not a function
        TypeError: _this.storage.forEach is not a function

存儲本身應該是可迭代的,但 jasmine 並不認為它是因為我嘲笑它的方式,我假設。

問題是:我如何正確地對這個位進行單元測試? 我不想為測試目的創建一個真實的存儲實例,有沒有辦法通過模擬將 this.storage 定義為可迭代的?

似乎Storage是一個數組。

試試這個快速解鎖:

providers: [
        { provide: Storage, useValue: [] },
      ],

我們正在為Storage提供一個空數組,因為我們正在執行this.storage.forEach( 。您可以根據自己的喜好修改此數組。

再次回答我自己的問題。

我的目標是保留我的間諜 object 以模擬storage.getstorage.set並能夠測試storage.forEach 這似乎是不可能的。 上面的答案可能適合那些只需要測試storage.forEach的人。

我根本不使用storage.forEach ,而是像這樣遍歷storage.keys

async getData(): Promise<Array<{key: string, value}>> {
    await this.initStorage();

    return this.storage.keys()
      .then(keys => Promise.all(keys
        .filter(key => key.startsWith('data-'))
        .map(async key => {
          const value = await this.storage.get(key);

          return {
            key: 'someKey',
            value,
          }
        })
      ));
  }

這會產生相同的結果並且更容易測試。 我只需要像這樣將 keys 方法添加到我現有的間諜中:

mockStorage = jasmine.createSpyObj('Storage', ['get', 'set', 'remove', 'create', 'keys']);

然后模擬返回值

mockStorage.keys.and.resolveTo(['different', 'storage', 'keys']);

從那里開始相當簡單。 希望這對將來的人有幫助。

暫無
暫無

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

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