我必须测试一个后端服务存根,该存根返回一个可观察值。 存根方法:
public postStatus(handle: string): Observable<StatusReturn>{
setTimeout(() => {
this.result = {
currentlyProcessedFileName: 'datei2.pdf',
errParams: [],
numFiles: 3,
numFilesAlreadyProcessed: 1,
numTasksBefore: 0,
processingStatus: 1,
technicalRetCode: 0
};
}, 5000);
setTimeout(() => {
this.result = {
currentlyProcessedFileName: '',
errParams: [],
numFiles: 3,
numFilesAlreadyProcessed: 3,
numTasksBefore: -1,
processingStatus: 2,
technicalRetCode: 0
};
}, 10000);
return of(this.result);
}
其他信息:结果在服务级别初始化,因此setTimeout仅更新这些参数。
我已经尝试了很多,但是我的“最接近”方法是:
fit('postStatus should return changeing Observable<StatusReturn> with correct second sample data after 5000ms', fakeAsync(() => {
// WHEN
const secondReturn = {
currentlyProcessedFileName: 'datei2.pdf',
errParams: [],
numFiles: 3,
numFilesAlreadyProcessed: 1,
numTasksBefore: 0,
processingStatus: 1,
technicalRetCode: 0
};
let result;
// DO
service.postStatus('handle').subscribe((res) => {
result = res;
});
tick(5001);
expect(result).toEqual(secondReturn);
}));
测试给出以下错误:
Expected $.currentlyProcessedFileName = '' to equal 'datei2.pdf'.
Expected $.numFilesAlreadyProcessed = 0 to equal 1.
Expected $.numTasksBefore = 1 to equal 0.
Expected $.processingStatus = 0 to equal 1.
其中左侧是初始数据(因此我从可观察的数据中获取数据)和
Error: 1 timer(s) still in the queue.
表示已启动第一次数据更新。我可以通过将tick(5001)
更改为tick(4999)
并在队列中有两个计时器来批准此操作。
我正在寻找有关如何使用新的可观察值更新结果变量的建议。
答案 0 :(得分:2)
我认为您的职能正在做您想要做的事情以外的事情。 我们可以通过添加一些console.log语句来进行测试。
service.postStatus('handle').subscribe((res) => {
console.log('setting return');
result = res;
});
console.log(`result is ${result}`);
tick(5001);
console.log('tick 5001 occurred');
日志:“设置收益”
日志:“结果未定义”
日志:“打勾5001”
这告诉我们您的订阅立即返回,因为这是我们看到的第一个控制台日志。由于计时器尚未触发,因此结果不确定。
由于您要返回一个可观察值并期望它具有两个不同的结果,因此我想为您的被测方法提出一种略有不同的方法。我们可以如下返回Subject<StatusReturn>
。
public postStatus(handle: string): Observable<StatusReturn> {
const currentStatus = new Subject<StatusReturn>();
setTimeout(() => {
this.result = {
currentlyProcessedFileName: 'datei2.pdf',
errParams: [],
numFiles: 3,
numFilesAlreadyProcessed: 1,
numTasksBefore: 0,
processingStatus: 1,
technicalRetCode: 0
};
currentStatus.next(this.result);
}, 5000);
setTimeout(() => {
this.result = {
currentlyProcessedFileName: '',
errParams: [],
numFiles: 3,
numFilesAlreadyProcessed: 3,
numTasksBefore: -1,
processingStatus: 2,
technicalRetCode: 0
};
currentStatus.next(this.result);
}, 10000);
return currentStatus;
}
是否通知我正在打电话给currentStatus.next(this.result)
,以告知受试者结果已更改?
使用此功能后,您可以稍微更改一下测试以使其看起来像
fit('postStatus should return changing Observable<StatusReturn> with correct second sample data after 5000ms', fakeAsync(() => {
// WHEN
const secondReturn = {
currentlyProcessedFileName: 'datei2.pdf',
errParams: [],
numFiles: 3,
numFilesAlreadyProcessed: 1,
numTasksBefore: 0,
processingStatus: 1,
technicalRetCode: 0
};
let result;
// DO
service.postStatus('handle').subscribe((res) => {
result = res;
});
tick(5001);
const firstResult = result;
expect(result).toEqual(secondReturn);
tick(5001); // clear the queue
expect(result).not.toEqual(firstResult);
}));