[英]Angular 2 mocking an async service that calls another service
I'm learning Angular 2 testing (Karma, Jasmine). 我正在学习Angular 2测试(Karma,Jasmine)。 I already have a working test for an HTTP service, largely pulled from this Semaphore tutorial on services and testing . 我已经有一个HTTP服务的工作测试,主要是从这个关于服务和测试的Semaphore教程中提取的。 I have the test working right through the usual async(inject([MyService], ... 我通过通常的异步(inject([MyService],...)进行测试。
My actual program has a service wrapped in a service, as below. 我的实际程序有一个包含在服务中的服务,如下所示。
@Injectable()
export class GlobalsService {
private options: Option[] = [];
error: any;
constructor(private optionService: OptionService) { }
public getGlobals(): void {
let that = this;
this.optionService
.getOptions()
.then(options => that.fillOptions(options))
.catch(error => that.error = error);
}
[SNIP]
The optionService.getOptions() returns a Promise which is waited for, then fills the globalService.options list. optionService.getOptions()返回等待的Promise,然后填充globalService.options列表。 The globalsService.getGlobals() is called either synchronously or in a place where the asynchronous (delayed) fill of its contents are hidden. globalsService.getGlobals()可以同步调用,也可以在隐藏其内容的异步(延迟)填充的位置调用。
export class AppComponent implements OnInit {
constructor(private globalsService: GlobalsService) { }
ngOnInit() {
this.globalsService.getGlobals();
}
[SNIP]
What I'm stuck at is how to call globalsService.getGlobals() in a testing context. 我坚持的是如何在测试环境中调用globalsService.getGlobals()。 I think I'm supposed to call it through async(). 我想我应该通过async()来调用它。
So far my mock OptionService is: 到目前为止,我的模拟OptionService是:
@Injectable()
export class MockOptionService {
constructor() { }
getOptions(): Promise<Option[]> {
let options: Option[] = [
{ id: 'NY' } // truncated property list
];
return Promise.resolve(options);
}
}
I then am planning to call it through: 然后我计划通过以下方式调用它:
it('should get Option objects async',
async(inject([GlobalsService, MockOptionService], (globalsService: GlobalsService, optionService: OptionService) => {
globalsService.getGlobals()
.then(() => {
expect(globalsService.getOptions().length).toBe(1);
});
However, my "smart" programmers editor (SublimeText) says that "Property 'then' does not exist on type 'void'.", leaving me unsure if I should have async(inject or just use a tick(). 但是,我的“智能”程序员编辑器(SublimeText)说“属性'然后'在类型'void'上不存在。”,让我不确定我是否应该异步(注入或只使用tick())。
Comments, anyone? 评论,有人吗?
Thanks, Jerome. 谢谢,杰罗姆。
Try this ! 尝试这个 !
it('should get Option objects async',
async(inject([GlobalsService, MockOptionService], (globalsService: GlobalsService, optionService: OptionService) => {
globalsService.getGlobals()
.do(value => {
expect(value.length).toBe(1);
}).toPromise();
})));
After fiddling around and more research I figured two things: * My test is wrong. 在摆弄并进行更多研究后,我想到了两件事:*我的测试是错误的。 globalsService.getGlobals() returns void. globalsService.getGlobals()返回void。 The .then, or .do, are correct in saying "property does not exist". .then或.do在说“属性不存在”时是正确的。
What I changed to make the test work is adding a setup clause, changing async(inject( to fakeAsync(inject( and to fixup the injections and declarations. Here is what works: 我改变测试工作的是添加一个setup子句,更改async(注入(对于fakeAsync(注入)以及修复注入和声明。这是有效的:
describe('Globals Service', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{ provide: OptionService, useClass: MockOptionService },
{ provide: GlobalsService, useClass: GlobalsService }
]
});
});
fakeAsync(inject([GlobalsService, OptionService], (globalsService: GlobalsService, optionService: OptionService) => {
globalsService.getGlobals();
tick();
expect(globalsService.getOptions().length).toBe(1);
})));
});
Thanks all for looking, and to Nidhin for replying. 感谢所有人的期待,并感谢Nidhin的回复。 Now I work on my error() handling -- that is reporting a null error variable in handleError(). 现在我处理我的error()处理 - 即在handleError()中报告一个空错误变量。 But that is for a different support call. 但这是针对不同的支持电话。
Jerome. 杰罗姆。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.