【问题标题】:Testing an API call in Angular 2在 Angular 2 中测试 API 调用
【发布时间】:2018-01-05 18:29:55
【问题描述】:

我有以下 2 个组件和一个由两者共享的服务。我需要对它们进行单元测试,但我无法弄清楚如何测试服务对以下组件的依赖性。

//a.component.ts
import { Component, Input } from '@angular/core';
import { Http, Response } from '@angular/http';
import { SharedService } from './shared/shared.service';

@Component({
  selector: 'a',
  providers: [],
  templateUrl: './a.component.html'
})
export class AComponent {
  ax = {};

  constructor(public helperService: SharedService) {
    helperService.getFromAPI().subscribe(data => this.ax = data["people"]);
  }

}



//b.component.ts
import { Component } from '@angular/core';
import { SharedService } from './shared/shared.service';
import { Subscription }   from 'rxjs/Subscription';


@Component({
  selector: 'b',
  providers: [],
  templateUrl: './b.component.html'
})

export class BComponent {
  subscription: Subscription;
  x = '';

  constructor(public helperService: SharedService) {}

  ngOnInit() {
    this.subscription = this.helperService.c$.subscribe(
      data => {
        this.x = data;
      });
  }
}

这是调用 API 的服务。另一个函数setC 在单击按钮时将值添加到可观察对象,并且该值将由BComponent 访问。

// shared.service
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/map';

@Injectable()
export class SharedService {

  private c = new Subject<string>();
  c$ = this.c.asObservable();

  constructor(
    private http: Http
  ) { }

  getFromAPI() {
    return this.http.get('url')
      .map((res: Response) => res.json());
  }

  setC(data: string) {
    this.c.next(data);
  }
}

如何在 Jasmine 中进行测试?到目前为止,我的努力都是徒劳的。

我尝试过这样做

it('xxx', inject([SharedService], (service: SharedService) => {
    const fixture = TestBed.createComponent(AComponent);
    const app = fixture.componentInstance;

    spyOn(service, 'c$').and.callThrough;

    service.setC('Random Name');
    expect(service.c$).toHaveBeenCalled();

  }));

Expected spy c$ to have been called. 测试失败。

【问题讨论】:

  • angularjs 标签仅适用于 Angular 1.x,适用于 Angular 2+ 使用标签:angular

标签: angular unit-testing jasmine spy


【解决方案1】:

您似乎在监视Observable,但是当您调用setC 时调用的是您主题的next 函数。所以你可能想监视它。

spyOn(service.c, 'next').and.callThrough() 之类的东西应该可以解决问题。

希望对你有帮助。


更新:如果您想明确测试 Observable 的功能,那么我只需订阅它,调用 setC 并测试响应,如下所示:

service.$c.subscribe((data) => {
    expect(data).toBe('foobar');
});
service.setC('foobar');

在评论中回答您的问题:由于您的 c 是私人的,您可以像这样监视它:spyOn(service['c'], 'next').and.callThrough()。 可能是您的 ide 会唠叨要监视私有方法,在这种情况下,您可以像这样添加 any 类型:spyOn&lt;any&gt;(...)

【讨论】:

  • 但是cprivate。我怎么能监视它?
  • @SadarAli 它本身并不能回答您的问题,但this question 可能会有所帮助
  • @lexith 如果我将c 删除为私有,则此技巧有效。如果我想使用类似的间谍来模拟 getFromAPI 调用(带有一些 json),我应该如何进行?
  • 你的意思是你将如何测试getFromApi?是的,在httpget 方法上使用间谍,例如spyOn&lt;any&gt;(service['http'], 'get'); 在您的组件中,您可能希望测试响应,但这是另一个问题(然后您必须使用MockBackend 模拟http)跨度>
猜你喜欢
  • 2017-05-01
  • 1970-01-01
  • 2017-04-04
  • 2017-11-23
  • 1970-01-01
  • 2018-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多