[英]Ionic Storage v3 - Unit Tests | TypeError: _this.storage.forEach is not a function
提示:本站为国内最大中英文翻译问答网站,提供中英文对照查看,鼠标放在中文字句上可显示英文原文。
我有一个用于@ionic/storage-angular
的StorageService
包装器,其中我有一个 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.get
和storage.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.