Ich habe einen Dienst (ChildService), der von einem anderen Dienst (InteractWithServerService) abhängt. Späterer Dienst (InteractWithServerService) wird verwendet, um Serveraufrufe auszuführen und eine Observable vom Typ "any" zurückzugeben. Der Einfachheit halber nehmen wir an, dass es beobachtbar zurückgegeben wird. Ich versuche Komponententest für ChildService zu schreiben.Unit-Test spyOn beobachtbarer Service in angular2
ChildService
@Injectable()
export class ApplicationService {
constructor(private interactWithServerService:InteractWithServerService){;}
public GetMeData():string {
var output:string;
this.interactWithServerService.get("api/getSomeData").
subscribe(response =>{console.log("server response:", response);
output=response});
return output;
}
}
ServerInteractionService
@Injectable()
export class InteractWithServerService {
constructor(private http: Http) {
;
}
get(url: string): Observable<any> {
return this.http.get(this.url);
}
}
Der Testfall funktioniert gut, wenn ich den abhängigen Dienst verspotten. d.h.
class MockInteractWithServerService {
get() {
return Observable.of("some text");
}
}
describe('Service:ChildService',() => {
let childService: ChildService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{ provide: InteractWithServerService, useClass: MockInteractWithServerService },
ChildService],
});
beforeEach(inject([ChildService], (actualService: ChildService) => {
childService= actualService;
}));
fit('should call server-call testCall()',() => {
let actualReturnvalue= childService.GetMeData();
expect(actualReturnvalue).toBe("some text");
});
});
Das oben beschriebene Verfahren ist nicht die bevorzugt als I „n“ mock Klassen für „n“ Abhängigkeiten vielleicht am Ende zu schreiben. Also möchte ich meine Unit Tests mit SpyOn erstellen. Der Testfall funktioniert jedoch nicht und wirft "Fehler: Kein Provider für Http!". Während ich verstehe, was der Fehler ist, möchte ich wissen, warum es geworfen wird, obwohl ich den abhängigen Dienst ausspioniere. Sieht so aus, als ob "SpyOn" nicht funktioniert.
describe('Service:ChildService',() => {
let childService: ChildService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
InteractWithServerService,
ChildService],
});
spyOn(InteractWithServerService.prototype, 'get').and
.callFake(()=>
{return Observable.of("some text");});
});
beforeEach(inject([ChildService], (actualService: ChildService) => {
childService= actualService;
}));
fit('should call server-call testCall()',() => {
let actualReturnvalue= childService.GetMeData();
expect(actualReturnvalue).toBe("some text");
});
});
Fehle ich etwas offensichtlich?
Dank @peeskillet. Klappt wunderbar. Es geht nur um "useValue" und die Rückgabe eines beliebigen Objekts für jede Methode, die Sie aufrufen. Es sieht definitiv dreckig aus (eher nicht so sauber). Ist das die Art und Weise, wie wir die Tests schreiben sollen? –
Ein "beliebiges Objekt" unterscheidet sich nicht wirklich von der Verwendung einer Scheinklasse. Einziger Unterschied ist, dass man in einer Klasse gekapselt ist. Am Ende sind sie beide nur willkürliche Objekte. Ihre Klasse erweitert die echte Service-Schnittstelle nicht. Was macht das nicht willkürlich? Es kommt nur darauf an, dass das Objekt die Methode hat, die aufgerufen wird. –
Nein, ich argumentiere, dass Scheinklassen besser sind als UseValue.Mein Punkt ist beides - Scheinklasse und UseValue-Lösung sieht im Vergleich zu alten Methoden nicht sauber aus, sondern injiziert nur abhängige Klassen und spioniert sie aus. –