【发布时间】:2019-05-18 22:41:17
【问题描述】:
我有一个服务,它创建了一个发出值的可观察对象,并且相对容易测试发出的值是否符合预期。
例如:
describe('service', () => {
beforeEach(() => {
TestBed.configureTestingModule({providers: [MyService]});
});
it('should emit true', async(() => {
const service = TestBed.get(MyService);
service.values$.subscribe((value) => expect(value).toBeTruthy());
}));
});
上面的方法可以测试期望值,但它只有在服务实际发出值时才有效。如果您遇到服务无法发出值的极端情况,那么测试本身实际上会通过并且 Jasmine 会记录警告消息“SPEC HAS NO EXPECTATIONS should be created”。
我在 Google 上搜索了一段时间,试图弄清楚如何将此案例视为错误并想出了这种方法。
it('should emit true', async(() => {
const service = TestBed.get(MyService);
let value;
service.values$.subscribe((v) => value = v);
expect(value).toBeTruthy();
}));
以上内容仅适用于同步 observables,对我来说就像代码异味。其他开发人员会看到这一点并认为这是一个低质量的测试。
所以在考虑了几天之后。我想过使用takeUntil() 来强制observable 完成,然后测试预期的结果。
例如:
describe('service', () => {
let finished: Subject<void>;
beforeEach(() => {
TestBed.configureTestingModule({providers: [MyService]});
finished = new Subject();
});
afterEach(() => {
finished.next();
finished.complete();
});
it('should emit true', async(() => {
const service = TestBed.get(MyService);
let value;
service.changes$
.pipe(
takeUntil(finished),
finalize(() => expect(value).toBeTruthy())
)
.subscribe((v) => value = v);
}));
});
在上面的例子中,值被存储在一个局部变量中,然后在 observable 完成时检查预期的结果。我通过使用afterEach() 和takeUntil() 来强制完成。
问题:
我的方法是否有任何副作用,如果有的话,执行此类测试的更 Angular/Jasmine 方式是什么。我担心您不应该在 afterEach() 生命周期调用期间执行 expect 断言。
【问题讨论】:
标签: javascript angular jasmine rxjs observable