我对Jest和RxJ相当陌生,并被要求测试Observable。
const testComponents = ['test-component-1', 'test-component-2', 'test-component-3']
const nrOfComponents = testComponents.length
test('Activities get added to the taskStack', (done) => {
launcher.observable$.subscribe((state) => {
expect(state.taskStack).toHaveLength(nrOfComponents)
done()
}
)
testComponents.forEach((name) => {
addActivityToTaskStack(name, 'standard')
})
})
显然,state.taskStack
数组的预期行为是三个。但是,添加第一项后测试已经完成。我如何等待Observable完成,然后才运行断言?
答案 0 :(得分:1)
第一个subscribe
回调在每个值上运行。测试应在可观察到的完成时结束,并且还应处理可能很乏味的错误:
let subscription = launcher.observable$.subscribe(
function onValue(state) {
try {
expect(state.taskStack).toHaveLength(nrOfComponents)
} catch (err) {
subscription.unsubscribe();
done.fail(err);
}
},
function onError(err) {
subscription.unsubscribe();
done.fail(err);
},
function onComplete() {
done();
}
)
如果一个可观察对象期望接收一个值然后完成,那么一种直接的方法是切换到promise,因为它们符合所描述的可观察对象的语义,并且由Jest固有地支持。
test('Activities get added to the taskStack', async () => {
const state = await launcher.observable$.toPromise();
expect(state.taskStack).toHaveLength(nrOfComponents)
})
如果有多个值,则可以在toPromise
之前收集它们以进行断言,例如toArray
运算符。
请注意,RxJS 7中不推荐使用toPromise
,而推荐使用lastValueFrom
。
答案 1 :(得分:1)
您只能获取流的数量,并在完成可观察性时调用done()
:
launcher.observable$
.pipe(
take(3) // <- number of items to be added. It will be completed after 3 items
)
.subscribe(
state => {
expect(state.taskStack).toHaveLength(testComponents.length);
},
() => {},
() => {
done();
}
);
不确定如何触发observable
,但是您可能需要更新expect
表达式。
但是,以上代码将确保在添加3
个项目之后完成测试。