如何测试 Observable<boolean>
How to test an Observable<boolean>
我有一个条件 returns 如下所示的 Observable:
app.component.ts
import { Observable } from "rxjs";
export class ProductComponent implements OnInit
ProductListLength: Number;
isProductListEmpty: Observable<boolean>;
}
ngOnInit(): void {
if(this.ProductListLength === 0)
this.isProductListEmpty = new Observable((observer) => observer.next(true))
}
else {
this.isProductListEmpty = new Observable((observer) => observer.next(false))
}
我尝试运行这些测试用例:
app.component.spec.ts
it('should return true when List is empty', () => {
component.productListLength = 0
fixture.detectChanges()
expect(component.isProductListEmpty).toBeTrue()
})
it('should return false when List not empty', () => {
component.productListLength = 2
fixture.detectChanges()
expect(component.isProductListEmpty).toBeFalse()
})
但是 运行ning ng test 我收到了这个:
错误:预期 Observable({_isScalar: false, _subscribe: Function}) 为真
如何正确测试这些案例?
您需要从可观察对象中获取值。您可以订阅它或使用异步等待。像下面这样的东西应该可以工作(未经测试)。
it('should return false when List not empty', async () => {
component.productListLength = 2
fixture.detectChanges();
const res = await component.isProductListEmpty.toPromise();
expect(res).toBeFalse()
})
编辑(应该可以解决超时问题)
it('should return false when List not empty', async () => {
component.productListLength = 2
component.ngOnInit();
const res = await component.isProductListEmpty.toPromise();
expect(res).toBeFalse()
})
您可以通过使用测试参数告诉它何时完成来使您的测试异步:
it('should return true when List is empty', (done) => {
component.productListLength = 0
fixture.detectChanges()
component.isProductListEmpty.subscribe(val => {
expect(val).toBeTrue();
done();
});
})
要添加到 Daniel Douglas
答案,我认为您需要使用 take
运算符。
import { take } from 'rxjs/operators';
it('should return false when List not empty', async () => {
component.productListLength = 2
fixture.detectChanges();
const res = await component.isProductListEmpty.pipe(take(1)).toPromise();
expect(res).toBeFalse()
})
我们必须 take(1)
因为我们采用第一个发射然后转换为承诺。您收到超时错误是因为如果您不进行第一次发射,承诺将永远不会解决(它会挂起)。
我也希望 fixture.detectChanges()
是您在测试套件中调用的第一个为您调用 ngOnInit
的人。否则,每次更新 isProductListEmpty
.
时都必须手动调用 ngOnInit
我有一个条件 returns 如下所示的 Observable:
app.component.ts
import { Observable } from "rxjs";
export class ProductComponent implements OnInit
ProductListLength: Number;
isProductListEmpty: Observable<boolean>;
}
ngOnInit(): void {
if(this.ProductListLength === 0)
this.isProductListEmpty = new Observable((observer) => observer.next(true))
}
else {
this.isProductListEmpty = new Observable((observer) => observer.next(false))
}
我尝试运行这些测试用例:
app.component.spec.ts
it('should return true when List is empty', () => {
component.productListLength = 0
fixture.detectChanges()
expect(component.isProductListEmpty).toBeTrue()
})
it('should return false when List not empty', () => {
component.productListLength = 2
fixture.detectChanges()
expect(component.isProductListEmpty).toBeFalse()
})
但是 运行ning ng test 我收到了这个: 错误:预期 Observable({_isScalar: false, _subscribe: Function}) 为真
如何正确测试这些案例?
您需要从可观察对象中获取值。您可以订阅它或使用异步等待。像下面这样的东西应该可以工作(未经测试)。
it('should return false when List not empty', async () => {
component.productListLength = 2
fixture.detectChanges();
const res = await component.isProductListEmpty.toPromise();
expect(res).toBeFalse()
})
编辑(应该可以解决超时问题)
it('should return false when List not empty', async () => {
component.productListLength = 2
component.ngOnInit();
const res = await component.isProductListEmpty.toPromise();
expect(res).toBeFalse()
})
您可以通过使用测试参数告诉它何时完成来使您的测试异步:
it('should return true when List is empty', (done) => {
component.productListLength = 0
fixture.detectChanges()
component.isProductListEmpty.subscribe(val => {
expect(val).toBeTrue();
done();
});
})
要添加到 Daniel Douglas
答案,我认为您需要使用 take
运算符。
import { take } from 'rxjs/operators';
it('should return false when List not empty', async () => {
component.productListLength = 2
fixture.detectChanges();
const res = await component.isProductListEmpty.pipe(take(1)).toPromise();
expect(res).toBeFalse()
})
我们必须 take(1)
因为我们采用第一个发射然后转换为承诺。您收到超时错误是因为如果您不进行第一次发射,承诺将永远不会解决(它会挂起)。
我也希望 fixture.detectChanges()
是您在测试套件中调用的第一个为您调用 ngOnInit
的人。否则,每次更新 isProductListEmpty
.
ngOnInit