带有jasmine的构造函数中的spyOn方法

时间:2016-05-26 10:09:50

标签: unit-testing typescript angular jasmine karma-runner

我想在我的单元测试中窥探一个承诺并伪造承诺,但问题是如果我首先运行构造函数,他首先运行承诺然后运行Spyon。

但是当我第一次运行spyOn然后运行构造函数时,它会给出一个错误,即存储未定义。

有人知道如何解决这个问题吗?

规格文件:

let injector: any = ReflectiveInjector.resolveAndCreate([SettingsService]);
    settingsService = injector.get(SettingsService);

    spyOn(settingsService.storage, 'get').and.callFake((key: String): Promise<string> => {
        return new Promise((resolve, reject) => { resolve('https://secure.info/pascal'); });
    });

构造

{{1}}

更新

我也尝试了这个:

{{1}}

1 个答案:

答案 0 :(得分:1)

您遇到的问题是您在构造函数中实例化存储,因此您无法从外部访问它。这意味着你无法嘲笑它。

在致电spyOn之前设置settingsService = new SettingsService();并不起作用,因为尚未创建字段存储空间。

您有两种方法可以解决这个问题:

使用以下代码模拟服务$ httpBackend 。以this post为例

beforeEach(inject(function($injector) {
    service = $injector.get('carService');
    $httpBackend = $injector.get('$httpBackend');

    $httpBackend.when('GET', "/api/cars/types").respond(["Toyota", "Honda", "Tesla"]);
}));

通过这种方式,您可以模拟调用this.storage.get('url')时获得的承诺并测试行为。

使存储成为服务并将其注入模拟:如果使用此方法,则可以模拟存储,从而模拟this.storage.get('url')的行为。你的类``的代码看起来像这样

static $inject = ['Storage'];
constructor(storage: Storage) {
    this.storage = storage;
    this.storage.get('url').then(data => {
        this.setLink(data);
    });
}

但这种方式取决于你如何定义和使用存储,所以通常第一种方式会更好