在angular2中进行单元测试spyOn的可观察服务 [英] unit testing spyOn observable service in angular2
问题描述
我有一个服务(ChildService),该服务依赖于另一个服务(InteractWithServerService).后者服务(InteractWithServerService)用于进行服务器调用并返回"any"类型的可观察对象.为了简单起见,我们假设它返回一个可观察的对象.我正在尝试为ChildService编写单元测试.
I have a service (ChildService) which depends on another service (InteractWithServerService). The latter service (InteractWithServerService) is used to make server calls and return an observable of "any" type. For simplicity let's assume it returns an observable. I am trying to write a unit test for ChildService.
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
ServerInteractionService
@Injectable()
export class InteractWithServerService {
constructor(private http: Http) {
;
}
get(url: string): Observable<any> {
return this.http.get(this.url);
}
}
当我模拟依赖服务时,测试用例工作正常.即
The test case works fine when I mock the dependent service. i.e.,
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的没有提供者!".虽然我理解错误是什么,但是我想知道为什么会抛出错误,尽管我在监视依赖服务.看起来"spyOn"无法正常工作.
The above method is not preferred as I might end up writing "n" mock classes for "n" dependencies. So I want to create my unit tests using spyOn. However, the test case doesn't work and throws "Error: No provider for Http!". While I understand what the error is, I would like to know why it is thrown although I am spying on the dependent service. Looks like the "spyOn" is not working.
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");
});
});
我缺少明显的东西吗?
推荐答案
但是,该测试用例不起作用,并抛出错误:Http的没有提供者!".
However, the test case doesn't work and throws "Error: No provider for Http!".
因为您仍然在providers
中拥有该服务,所以Angular仍试图创建它
Because you still have the service in the providers
, so Angular is trying to create it still
providers: [
InteractWithServerService,
ChildService],
除了创建模拟类 外,您可以做的只是做类似的事情
What you can do instead of creating a mock class is to just do something like
providers: [
{
provide: InteractWithServerService,
useValue: { get: Observable.of(..) }
}
]
在这里,您正在使用提供任何对象的useValue
.那将是注射时使用的值.在上述情况下,它只是您的模拟方法中的任意对象.
Here's you're using useValue
which provide any object. That will be the value used when injected. In the case above, it is just some arbitrary object with your mock method.
如果您想监视以便提供不同的值,可以注入InteractWithServerService
,然后执行
If you want to spy so that you can provide different values, you could inject the InteractWithServerService
, and then do
spyOn(service, 'get').and.returnValue(Observable.of(...))
// do test
您可以做的另一件事是用一个虚拟对象模拟Http
Another thing you could do is mock the Http with a dummy object
{ provide: Http, useValue: {} }
现在InteractWithServerService
将可以正常工作(只需将类添加到您当前拥有的提供者中).而且你可以监视它
Now the InteractWithServerService
will work (just adding the class to the providers` like you currently have). And you can just spy on it
let service = TestBed.get(InteractWithServerService);
spyOn(service, 'get').and.returnValue(..)
// do test
这篇关于在angular2中进行单元测试spyOn的可观察服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!