angular - Angular - 对组件构建中的承诺进行单元测试
问题描述
假设以下组件的构造函数和函数调用:
constructor(private fooService: FooService){
this.getBarFromService()
}
getBarFromService = () => fooService.getBar().then(bar => this.bar = bar)
服务的粗制getBar()
函数应该等待 API 结果:
getBar() {
let bar = null;
await new Promise((resolve, reject) => {
this.barBuilder.get('/bar').then(
data => resolve(bar = data), // data = baz
error => reject(error)
)
return bar;
}
我现在想尝试编写一个单元/集成测试来确定组件可以在不调用 API 的情况下请求和显示数据。从我读过的内容来看,我需要模拟该服务,以便它不会barBuilder
在现实中调用,而是立即返回一个值。这导致了以下测试文件:
beforeEach(() =>{
let mockFooService = jasmine.createSpyObj('FooService', ['getBar']);
mockFooService.getBar.and.returnValue(Promise.resolve(baz))
TestBed.configureTestingModule({
providers: [{provide: FooService, useValue: mockFooService}],
}).compileComponents();
});
describe('get bar should return baz', () => {
expect(component).toBeTruthy();
component.getBar();
fixture.detectChanges();
expect(component.bar).toBe(baz)
}
由于原始getBar()
函数在已解析的 Promise 对象中返回数据,而不是数据本身,因此我必须重新创建所述解析,否则测试将失败,说它无法处理then()
调用块。这样做后,它给了我一个想法,即测试在功能级别上工作,随着测试的进行,我会假设then()
块中的操作已经执行。
但是,baz
在构造和手动调用之后,该值尚未应用于组件,并且没有指针可以查看错误所在。在每个期望之间随意投掷console.log()
表明component.bar
在每个点上都保持为空。我也没有找到一个合理的答案,比如使用fakeAsync
等等。不适用,因为getBarFromService()
函数本身不是异步的。
因此,我不知所措,Angular (v8) 和 Jasmine 的文档都被严格遵守(尽我所能。)
问题响起;我如何能够找到为什么以及在模拟和/或单元测试本身baz
中没有应用变量的位置component.bar
,以及我将如何解决它?
解决方案
你必须使用async()
和whenStable()
describe('get bar should return baz', async(() => {
expect(component).toBeTruthy();
component.getBar();
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(component.bar).toBe(baz);
});
}));
附带说明一下,您getBar
可以大大简化为:
getBar() {
return this.barBuilder.get('/bar');
}
该.get
方法已经返回了一个承诺。因此无需将其包装在new Promise
. 如果你想在你的方法中使用 bar 变量,你可以这样做:
async getBar() {
const bar = await this.barBuilder.get('/bar');
return bar;
}
推荐阅读
- wordpress - 流 URL 未在 WordPress 上播放
- mongodb - 在分片 mongodb 集合中加载文档后,我可以创建索引吗?
- javascript - 如何更新材料设计精简版徽章计数
- matlab - 哪个函数在弃用后取代了 R2016a 的 svmtrain?
- scala - Scala-Z3:如何对对象执行成员访问
- javascript - Lit-Html“object Object”代码显示在浏览器中
- java - 从Java(Spring)过滤器重定向浏览器中的角度js页面
- python - 如何使用 Python 突出显示 pdf 中的特定行/文本
- android - 对于应用程序,如何仅验证和同步联系人列表中的手机号码?
- node.js - 如何配置要从其示例链接的父库(在 TS 中)?