大约3个月前,我问过这个问题(earlier question)关于测试一个服务,该服务有一个方法可以检查可用的浏览器配额存储并返回一个Observable。由于此服务的功能仅适用于Google Chrome,因此我将其更改为适用于Firefox。该服务现在看起来如下:
import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Observable";
import * as bowser from "bowser";
@Injectable()
export class StorageService {
hasAvailableStorage(): Observable<boolean> {
if (!bowser.chrome && !bowser.firefox) {
return Observable.create(obs => obs.next(true));
}
if (bowser.chrome || bowser.firefox) {
return Observable.create(observer => {
(navigator as any).storage.estimate().then(
estimate => {
observer.next(estimate.usage <= estimate.quota * 0.8);
});
});
}
}
}
我想对此服务进行单元测试,因此我创建了一个包含以下内容的规范文件:
import { Injectable } from "@angular/core";
import { StorageService } from "./storage.service";
@Injectable()
class MockStorage {
estimate() {
return { usage: 10, quota: 15 };
}
}
describe("storage.service", () => {
let service: StorageService;
beforeAll(() => service = new StorageService());
it("should return the result of hasAvailableStorage()", () => {
const spy = spyOn(navigator["storage"], "estimate").and.callFake(MockStorage);
service.hasAvailableStorage().subscribe(() => {
expect(spy).toHaveBeenCalled();
});
});
});
运行此测试时,我得到以下TypeError:
Cannot read property 'then' of undefined
我真的不明白:
除此之外,我想知道是否有类似的东西适用于IE? (我在互联网上找不到明确的解释......)
如果有人可以帮助我并在细节中提供一些例子,那将是很棒的! :)
答案 0 :(得分:1)
我不知道你的IE问题,但对于你的问题,那是因为你返回一个对象而不是一个承诺。这很容易看出:你的模拟没有返回then
。
由此,两个解决方案:你要么模仿一个承诺,要么模仿回报。我会去第二个。
class MockStorage {
estimate() {
return Promise.resolve({ usage: 10, quota: 15 });
}
}