对于我正在进行的项目,我遇到了Angular2单元测试的问题。
我创建了一个服务的模拟实现(我的“生产”代码):
updatePayment(orderId?: String) {
return Observable.of({
approvalLink: 'http://foo.bar'
});
}
然后我为它写了单元测试:
it('should return an object containing an approvalLink', async(inject(
[PaymentService],
(service: PaymentService) => {
service.updatePayment()
.subscribe((data) => {
expect(data.approvalLink).toEqual('http://foo.bar/');
});
}
)));
我把它放在异步区域中,因为据我所知,zone.js会在使用async()包装我的调用时等待所有异步操作完成。我知道我可以使用jasmines done()
或fakeAsync
区域和tick()
,但我希望得到关于async()
的观点。
到目前为止,这很好,这很有用。问题是在将生产代码更改为此后仍然有效:
updatePayment(orderId?: String) {
if (!orderId) {
orderId = null;
}
return this.http.post('/updatePayment', {
'orderId': orderId || ''
})
.map((data: any) => {
return {
approvalLink: data.json().approvalLink
}
});
}
我已经向我的TestBed提供程序添加了MockBackend
,但我还没有模拟响应(所以还没有mockBackend.connections.subscribe...
)。
但它仍然有效。进一步仔细研究表明,subscribe()块根本没有执行(我猜因为Observable从不发出值)。但这不是async()
的感觉吗?我所期望的是,这会因为没有任何反应而进入超时状态。或者单元测试可能永远不会完成。即使抛出一个Expection对我来说也没关系,但为什么它只是通过了测试而没有执行逻辑,虽然我明确地说,我现在正在做异步的东西?
这可以并且还执行subscribe()回调:
fit('should get a approvalLink back', async(inject(
[MockBackend, PaymentService],
(mockBackend: MockBackend, service: PaymentService) => {
mockBackend.connections.subscribe(connection => {
let response;
response = new Response(new ResponseOptions({
body: JSON.stringify({
approvalLink: 'http://foo.bar'
})
}));
connection.mockRespond(response);
});
service.updatePayment()
.subscribe((data) => {
expect(data.approvalLink).toEqual('http://foo.bar');
});
}
)));
再次 - 我知道如何解决问题,但也许有人可以给我一些见解,帮助我理解那个异步区域是什么......
提前致谢, 大卫