【问题标题】:Angular 5: Testing a service with native method and .thenAngular 5:使用本机方法和 .then 测试服务
【发布时间】:2018-04-23 10:48:26
【问题描述】:

大约 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();
        });
    });
});

运行此测试时,我收到以下类型错误:

Cannot read property 'then' of undefined

我不太明白:

  1. 为什么估计()未定义
  2. 如何修复测试

除此之外,我想知道是否有类似的东西也适用于 IE? (我在互联网上没有找到明确的解释......)

如果有人能帮助我并提供一些详细的例子,那就太好了! :)

【问题讨论】:

    标签: angular unit-testing angular5


    【解决方案1】:

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

    因此,有两种解决方案:要么模拟一个承诺,要么模拟返回。我会去第二个。

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

    【讨论】:

    • 感谢您的评论!我明白,但您建议的解决方案显示相同的错误。
    • 停止调用 fake,开始调用,并将你的 mock 直接注入到你的测试中
    • 或者直接窥探仓库:spyOn(navigator, "storage").and.returnValue(MockStorage)
    • 它甚至可以与 callThrough 一起使用而无需注入模拟:const spy = spyOn(navigator["storage"], "estimate").and.callThrough(); 感谢您的回复!
    • 无法以您显示的方式直接监视存储,因为它会给出错误:(TS) Argument of type "storage" is not assignable to parameter of type '"authentication" | "cookieEnabled" | "gam...',并显示参数类型不匹配的消息。
    猜你喜欢
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-20
    相关资源
    最近更新 更多