在 Angular 2 中测试 API 调用
Testing an API call in Angular 2
我有以下 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.
的测试。
你似乎在监视一个 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<any>(...)
我有以下 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.
的测试。
你似乎在监视一个 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<any>(...)