Mam usługę (ChildService), która zależy od innej usługi (InteractWithServerService). Późniejsza usługa (InteractWithServerService) służy do wywoływania serwera i zwracania obserwowalnego typu "any". Dla uproszczenia przyjmijmy, że zwraca on obserwowalne. Próbuję napisać test jednostkowy dla ChildService.testowanie jednostki spyOn obserwowalna usługa w 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);
}
}
Przypadek testowy działa dobrze, kiedy drwić usługi zależnej. tj
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");
});
});
Powyższy sposób nie jest korzystne, jako że może skończyć się na piśmie „n” próbne klas „n” zależności. Dlatego chcę utworzyć moje testy jednostkowe za pomocą spyOn. Jednak przypadek testowy nie działa i generuje "Błąd: brak dostawcy dla Http!". Chociaż rozumiem, co to jest błąd, chciałbym wiedzieć, dlaczego jest on rzucany, mimo że szpieguję usługę zależną. Wygląda na to, że "spyOn" nie działa.
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");
});
});
Czy brakuje mi czegoś oczywistego?
Dzięki @peeskillet. Działa jak marzenie. Jedyne, co dotyczy, to "useValue" i zwracanie arbitralnego obiektu dla każdej metody, którą będziesz wywoływać. Zdecydowanie wygląda na brudny (raczej nie taki czysty). Czy w ten sposób kątowe chce, abyśmy napisali testy? –
"Obiekt arbitralny" tak naprawdę nie różni się od używania fałszywej klasy. Jedyną różnicą jest to, że jeden jest zamknięty w klasie. W końcu są one po prostu dowolnymi obiektami. Twoja klasa nie rozszerza rzeczywistego interfejsu usługi. Co sprawia, że nie jest to arbitralne? Liczy się tylko to, że obiekt ma metodę, która zostanie wywołana. –
Nie sposób twierdzę, że fałszywe klasy są lepsze niż useValue.Chodzi mi o to, że zarówno klasa próbna, jak i rozwiązanie useValue nie wyglądają na czyste w porównaniu ze starym sposobem, po prostu wstrzykując klasy zależne i szpiegując je. –