我有一个名为GoodsDataService的服务。它通过Http服务获取一些数据。 Here is it
构造函数是:
constructor(private http: Http) {}
功能getGoods
。它是通过Http服务获取数据,get方法:
getGoods(): Promise<Good[]> {
return this.http.get(this.goodsUrl)
.toPromise()
.then(response => response.json().data as Good[])
.catch(this.handleError);
}
注意toPromise
方法。我是从this Angular official tutorial学到的。
现在关于getGoods
方法的单元测试。以下是GoodsDataService的单元测试:here。 This is how I test this method:
service.getGoods()
.then(goods => {
expect(goods.length).toEqual(10);
expect(goods).toEqual([new Good()]);
});
getGoods
进行http调用,因此I have to mock it。这是代码:
const mockResponse = [
{id: 11, name: 'Mr. Nice'},
{id: 12, name: 'Narco'},
{id: 13, name: 'Bombasto'},
{id: 14, name: 'Celeritas'},
{id: 15, name: 'Magneta'},
{id: 16, name: 'RubberMan'},
{id: 17, name: 'Dynama'},
{id: 18, name: 'Dr IQ'},
{id: 19, name: 'Magma'},
{id: 20, name: 'Tornado'}
];
mockBackend.connections.subscribe((connection) => {
connection.mockRespond(new Response(new ResponseOptions({
body: JSON.stringify({data: mockResponse})
})));
});
结果我有绿色测试。但由于这一点,他们不能成为绿色:expect(goods).toEqual([new Good()]);
。结果必须为红色。无论如何,即使我把调试器放在then
成功函数中(我预期的两个位置)IDE将在断点处停止,我会得到这个错误:
错误:未捕获(在承诺中):TypeError:无法读取属性&#39; length&#39;未定义的
所以,尽管我用一些数据模拟真实的http请求,但我在成功处理程序中得到undefined
,我将其传递给then
方法返回的承诺的getGoods
。
问题可能出在these lines:
...
.then(response => response.json().data as Good[])
...
如果我将调试器放在那里,我每次都会看到response.json().data
为undefined
。顺便说一句,这段代码会触发两次(不是一次)。我认为这可以通过rxjs解释(http.get不仅会返回一次observable和subscription fire。如果我检查response.json()
值是Promise。它被拒绝了。它中有一些错误堆栈跟踪。
就是这样:
TypeError: Already read
at eval (eval at <anonymous> (http://localhost:9876/base/src/test.ts:56782:13), <anonymous>:1:10)
at http://localhost:9876/base/src/test.ts:56782:13
at ZoneDelegate.invoke (http://localhost:9876/base/src/polyfills.ts:1546:26)
at ProxyZoneSpec.Array.concat.ProxyZoneSpec.onInvoke (http://localhost:9876/base/src/test.ts:55337:39)
at ZoneDelegate.invoke (http://localhost:9876/base/src/polyfills.ts:1545:32)
at Zone.run (http://localhost:9876/base/src/polyfills.ts:1296:43)
at http://localhost:9876/base/src/polyfills.ts:1972:57
at ZoneDelegate.invokeTask (http://localhost:9876/base/src/polyfills.ts:1579:31)
at ProxyZoneSpec.Array.concat.ProxyZoneSpec.onInvokeTask (http://localhost:9876/base/src/test.ts:55361:39)
at ZoneDelegate.invokeTask (http://localhost:9876/base/src/polyfills.ts:1578:36)
这段代码是如何创建的?我从this off tutorial和this great article学习。问题可能出在这里:看起来文章作者使用另一种方式来获取数据(他只使用订阅,没有承诺)。可能就是为什么我的测试不起作用。
可能我的问题与What does this error mean — Uncaught TypeError: Already read?有关。但是如何处理呢?
请注意,如果我在其他组件中使用服务 - 一切都像魅力一样!例如这段代码:
ngOnInit() {
this.goodsDataService.getGoods()
.then((data) => {
debugger;
})
}
在data
中显示正确的数据(数组)。
问题:我做错了什么?
有什么想法吗?