Angular 如何测试服务模拟中可观察到的更改?

Angular 如何测试服务模拟中可观察到的更改?,angular,unit-testing,asynchronous,observable,Angular,Unit Testing,Asynchronous,Observable,我必须测试一个后端服务存根,它返回一个可观察的。 存根方法: public postStatus(handle: string): Observable<StatusReturn>{ setTimeout(() => { this.result = { currentlyProcessedFileName: 'datei2.pdf', errParams: [], numFiles: 3, nu

我必须测试一个后端服务存根,它返回一个可观察的。 存根方法:

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);
  }
左侧是初始数据(所以我从可观察数据中获取数据),并且

这表示启动了第一次数据更新。我可以通过将
tick(5001)
更改为
tick(4999)
来批准此操作,并且有两个计时器在队列中


我正在寻找关于如何用新的可观察值更新结果变量的建议。

我认为您的函数所做的不是您想要的。 我们可以通过添加一些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”

这告诉我们您的订阅立即返回,因为这是我们看到的第一个控制台日志。由于计时器尚未启动,因此结果未定义

由于您返回的是一个可观察对象,并期望它有两个不同的结果,因此我想为您的测试方法建议一种稍微不同的方法。我们可以返回
主题
,如下所示

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;
}
Error: 1 timer(s) still in the queue.
service.postStatus('handle').subscribe((res) => {
    console.log('setting return');
    result = res;
});
console.log(`result is ${result}`);

tick(5001);
console.log('tick 5001 occurred');
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;
}
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);
}));