我编写了一个过滤可观察输入的管道。在管道中,我使用timeout()运算符指定一个超时,以在源未及时发出期望值的情况下中止等待。
我想用茉莉花大理石测试超时情况,但无法正常工作。
我相信 expect(source).toBeObservable()
在源发出之前进行评估。
请参阅Stackblitz
要测试的管道:
source = cold('a', { a: { id: 'a' } }).pipe(
timeout(500),
filter((a) => false),
catchError((err) => {
return of({ timeout: true })
}),
take(1)
);
使用toPromise()进行测试按预期进行:
expect(await source.toPromise()).toEqual({ timeout: true });
用茉莉花大理石进行测试
const expected = cold('500ms (a|)', { a: { timeout: true } });
expect(source).toBeObservable(expected);
失败,并显示错误
Expected $.length = 0 to equal 2.
Expected $[0] = undefined to equal Object({ frame: 500, notification: Notification({ kind: 'N', value: Object({ timeout: true }), error: undefined, hasValue: true }) }).
Expected $[1] = undefined to equal Object({ frame: 500, notification: Notification({ kind: 'C', value: undefined, error: undefined, hasValue: false }) }).
答案 0 :(得分:1)
最近为茉莉花大理石0.5.0添加了对时间进展的支持(see jasmine-marbles PR #38)。软件包中添加了其他测试规范,这些规范说明了完成所需目标的两种可能方法之一。这是一些我可以使用Stackblitz示例将其组合在一起的选项。
在测试方法之外(例如,在beforeEach
中初始化可观察的源时,必须显式初始化并将测试调度程序传递给timeout
,以使expect().toBeObservable()
正常工作。但是,请注意,此更改将破坏“应该与toPromise一起使用”测试。 (我不知道为什么,但是toPromise()
似乎不适用于这种方法。)
describe('Marble testing with timeout', () => {
let source;
beforeEach(() => {
// You must explicitly init the test scheduler in `beforeEach`.
initTestScheduler()
source = cold('a', { a: { id: 'a' } }).pipe(
// You must explicitly pass the test scheduler.
timeout(500, getTestScheduler()),
filter((a) => false),
catchError(err => {
return of({ timeout: true })
}),
take(1)
);
});
it('should work with toBeObservable', () => {
const expected = cold('500ms (a|)', { a: { timeout: true } });
expect(source).toBeObservable(expected);
});
});
您可以稍作重构,并初始化测试方法({{1}中的 not )中可观察到的源。您无需显式初始化测试调度程序(茉莉花色大理石将在测试方法运行之前为您完成),但是您仍然必须将其传递给beforeEach
。请注意如何将timeout
函数与测试调度程序或默认调度程序一起使用(如果将createSource
参数保留为scheduler
)。此选项适用于“应与toPromise一起使用”测试和“应与toBeObservable”一起使用。
undefined
最后,如果您明确使用测试计划程序的describe('Marble testing with timeout', () => {
const createSource = (scheduler = undefined) => {
return cold('a', { a: { id: 'a' } }).pipe(
// You must explicitly pass the test scheduler (or undefined to use the default scheduler).
timeout(500, scheduler),
filter((a) => false),
catchError(err => {
return of({ timeout: true })
}),
take(1)
);
};
it('should work with toPromise', async () => {
const source = createSource();
expect(await source.toPromise()).toEqual({ timeout: true });
});
it('should work with toBeObservable', () => {
const source = createSource(getTestScheduler());
const expected = cold('500ms (a|)', { a: { timeout: true } });
expect(source).toBeObservable(expected);
});
});
方法,则可以跳过将测试计划程序传递给timeout
的步骤,但是必须使用run
(而不是expectObservable
。它可以正常工作,但是Jasmine将报告警告“ SPEC HA EXPECTATIONS”。
expect().toBeObservable()