单元测试angular 11个服务存根问题
Unit testing angular 11 service stub problem
我正在尝试 运行 对我的组件进行单元测试。
component.ts:
async ngOnInit(): Promise<void> {
await this.dataProviderService.getCurrencyCodesList().then(data => {
this.currencyList = data;
});
this.currencyList.sort((a, b) => {
return a.code > b.code ? 1 : -1;
});
// ...
}
使用的服务方式:
async getCurrencyCodesList(): Promise<any[]> {
// ...
const currencyCodes = currencyList.map(data => {
return {code: data.code, currency: data.currency, table: data.table};
});
return currencyCodes;
}
在 spec.ts 文件中,我尝试创建一个存根
//...
it('should have currencies in the list', () => {
expect(component.currencyList.length).toBeGreaterThan(1);
});
});
class DataProviderServiceStub {
async getCurrencyCodesList(): Promise<Observable<any[]>> {
return of ([{code: 'PLN', table: 'A'},
{code: 'EUR', table: 'A'}]);
}
}
// then this:
class DataProviderServiceStub {
async getCurrencyCodesList(): Promise<any[]> {
return ([{code: 'PLN', table: 'none'},
{code: 'EUR', table: 'A'}]);
}
}
//also tried return (of)([]), ([{}]) etc.
问题是我在从存根获取的数组上使用 .sort 时遇到这样的 Karma 错误:
Error: Uncaught (in promise): TypeError: this.currencyList.sort is not a function
TypeError: this.currencyList.sort is not a function
它有时显示为错误,有时显示为 AfterAll 错误,有时显示一切正常。我做错了什么?
测试结果失败:“类型错误:无法读取未定义的 属性 'length'”
getCurrencyCodesList()
方法是异步的,当你运行this.currencyList.sort
时,this.currencyList
还没有收到data
,它还不是数组因此没有 sort()
函数
您可以将 Array
类型设置为 currencyList
private currencyList: any []
调用 OnInit 后,将执行此块:
this.dataProviderService.getCurrencyCodesList()
接下来,then
块被推送到微任务队列并安排调用:
.then(data => {
this.currencyList = data;
});
然后进入this.currencyList.sort
由于 then
块仍在排队并且承诺仍未解决,因此没有任何内容分配给 currencyList
,因此它包含 undefined
或启动时分配给它的任何内容。它在 undefined
上调用 sort
方法。由于 undefined
没有 sort
方法,它会抛出错误。
如果您使用 async/await,为什么要调用 then
?这就是 async/await
的实现方式。
async ngOnInit(): Promise<void> {
this.currencyList = await this.dataProviderService.getCurrencyCodesList();
this.currencyList.sort((a, b) => {
return a.code > b.code ? 1 : -1;
});
// ...
}
它基本上等到 getCurrencyCodesList()
promise 已解决并将响应写入 currencyList
字段。然后它进一步进行常规同步流程。
由于您使用的是承诺,因此您的存根也应该 return 承诺而不是可观察的。在你的情况下,我会使用茉莉花间谍而不是存根进行测试,例如:
const localizationProviderSpy = jasmine.createSpyObj<LocalizationProviderService>('LocalizationProviderService', ['getCurrencyCodesList']);
将间谍添加到您的提供商列表中,您很可能正在使用 TestBed,然后像这样在您的测试用例中使用它:
it('should have currencies in the list', async () => {
const expected = [{code: 'PLN', table: 'A'}, {code: 'EUR', table: 'A'}];
localizationProviderSpy
.getCurrencyCodesList
.and
.returnValue(Promise.resolve(expected));
await component.ngOnInit();
expect(component.currencyList.length).toBeGreaterThan(1);
expect(component.currencyList).toEqual(expected);
});
我正在尝试 运行 对我的组件进行单元测试。
component.ts:
async ngOnInit(): Promise<void> {
await this.dataProviderService.getCurrencyCodesList().then(data => {
this.currencyList = data;
});
this.currencyList.sort((a, b) => {
return a.code > b.code ? 1 : -1;
});
// ...
}
使用的服务方式:
async getCurrencyCodesList(): Promise<any[]> {
// ...
const currencyCodes = currencyList.map(data => {
return {code: data.code, currency: data.currency, table: data.table};
});
return currencyCodes;
}
在 spec.ts 文件中,我尝试创建一个存根
//...
it('should have currencies in the list', () => {
expect(component.currencyList.length).toBeGreaterThan(1);
});
});
class DataProviderServiceStub {
async getCurrencyCodesList(): Promise<Observable<any[]>> {
return of ([{code: 'PLN', table: 'A'},
{code: 'EUR', table: 'A'}]);
}
}
// then this:
class DataProviderServiceStub {
async getCurrencyCodesList(): Promise<any[]> {
return ([{code: 'PLN', table: 'none'},
{code: 'EUR', table: 'A'}]);
}
}
//also tried return (of)([]), ([{}]) etc.
问题是我在从存根获取的数组上使用 .sort 时遇到这样的 Karma 错误:
Error: Uncaught (in promise): TypeError: this.currencyList.sort is not a function
TypeError: this.currencyList.sort is not a function
它有时显示为错误,有时显示为 AfterAll 错误,有时显示一切正常。我做错了什么?
测试结果失败:“类型错误:无法读取未定义的 属性 'length'”
getCurrencyCodesList()
方法是异步的,当你运行this.currencyList.sort
时,this.currencyList
还没有收到data
,它还不是数组因此没有 sort()
函数
您可以将 Array
类型设置为 currencyList
private currencyList: any []
调用 OnInit 后,将执行此块:
this.dataProviderService.getCurrencyCodesList()
接下来,then
块被推送到微任务队列并安排调用:
.then(data => {
this.currencyList = data;
});
然后进入this.currencyList.sort
由于 then
块仍在排队并且承诺仍未解决,因此没有任何内容分配给 currencyList
,因此它包含 undefined
或启动时分配给它的任何内容。它在 undefined
上调用 sort
方法。由于 undefined
没有 sort
方法,它会抛出错误。
如果您使用 async/await,为什么要调用 then
?这就是 async/await
的实现方式。
async ngOnInit(): Promise<void> {
this.currencyList = await this.dataProviderService.getCurrencyCodesList();
this.currencyList.sort((a, b) => {
return a.code > b.code ? 1 : -1;
});
// ...
}
它基本上等到 getCurrencyCodesList()
promise 已解决并将响应写入 currencyList
字段。然后它进一步进行常规同步流程。
由于您使用的是承诺,因此您的存根也应该 return 承诺而不是可观察的。在你的情况下,我会使用茉莉花间谍而不是存根进行测试,例如:
const localizationProviderSpy = jasmine.createSpyObj<LocalizationProviderService>('LocalizationProviderService', ['getCurrencyCodesList']);
将间谍添加到您的提供商列表中,您很可能正在使用 TestBed,然后像这样在您的测试用例中使用它:
it('should have currencies in the list', async () => {
const expected = [{code: 'PLN', table: 'A'}, {code: 'EUR', table: 'A'}];
localizationProviderSpy
.getCurrencyCodesList
.and
.returnValue(Promise.resolve(expected));
await component.ngOnInit();
expect(component.currencyList.length).toBeGreaterThan(1);
expect(component.currencyList).toEqual(expected);
});