Angular 5:使用本机方法和.then测试服务

时间:2018-04-23 10:48:27

标签: angular unit-testing angular5

大约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

我真的不明白:

  1. 为什么估计()未定义
  2. 如何修复测试
  3. 除此之外,我想知道是否有类似的东西适用于IE? (我在互联网上找不到明确的解释......)

    如果有人可以帮助我并在细节中提供一些例子,那将是很棒的! :)

1 个答案:

答案 0 :(得分:1)

我不知道你的IE问题,但对于你的问题,那是因为你返回一个对象而不是一个承诺。这很容易看出:你的模拟没有返回then

由此,两个解决方案:你要么模仿一个承诺,要么模仿回报。我会去第二个。

class MockStorage {
  estimate() {
    return Promise.resolve({ usage: 10, quota: 15 });
  }
}