модуль тестирования службы spyon observable в angular2
у меня есть служба (ChildService), которая зависит от другой службы (InteractWithServerService). Более поздняя служба (InteractWithServerService) используется для выполнения вызовов сервера и возврата наблюдаемого типа "любой". Для простоты предположим, что он возвращает observable. Я пытаюсь написать модульный тест для ChildService.
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);
}
}
тестовый случай отлично работает, когда я издеваюсь над зависимой службой. т. е.
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");
});
});
вышеуказанный метод не является предпочтительным, поскольку я мог бы в конечном итоге написать " N "макетных классов для" n " зависимостей. Поэтому я хочу создать модульные тесты с помощью spyOn. Однако тестовый случай не работает и выдает " Ошибка: нет поставщика для Http!". Хотя я понимаю, что такое ошибка, Я хотел бы знать, почему она брошена, хотя я шпионю за зависимой службой. Похоже, "шпион" не работает.
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");
});
});
я упускаю что-то очевидное?
1 ответов
однако тестовый случай не работает и выдает " ошибку: нет поставщика для Http!".
потому что у вас еще есть служба в providers
, поэтому Angular пытается создать его еще
providers: [
InteractWithServerService,
ChildService],
что вы можете сделать вместо создания макета класс это просто что-то вроде
providers: [
{
provide: InteractWithServerService,
useValue: { get: Observable.of(..) }
}
]
вот вы используете useValue
, которые предусматривают какого-либо объекта. Это будет значение, используемое при инъекции. В приведенном выше случае, это просто какой-то произвольный объект с вашим методом mock.
если вы хотите шпионить, чтобы вы могли предоставить разные значения, вы можете ввести InteractWithServerService
, а потом делать
spyOn(service, 'get').and.returnValue(Observable.of(...))
// do test
еще одна вещь, которую вы могли бы сделать, это издеваться над Http с фиктивным объектом
{ provide: Http, useValue: {} }
теперь InteractWithServerService
будет работать (просто добавив класс к провайдерам, как у вас в настоящее время). И вы можете просто шпионить за ним
let service = TestBed.get(InteractWithServerService);
spyOn(service, 'get').and.returnValue(..)
// do test