无法使用嵌入式 setInterval 进行观察以在测试中工作

问题描述

我为倒数计时器编写了一个小控制器类。在网页上工作正常,但我无法让我的单元测试工作。我不确定问题是我运行测试的方式还是课程本身的问题。

Here is the class under test:

import { Observable,Subscription } from 'rxjs'

    export class CountDownTimerController {
         public secondsTimer$ : Observable<any>;
         private counter : number;
         private _counteractive: boolean;
        
         public get counteractive(): boolean {
            return this._counteractive;
        }
         
        constructor() {
            this.counter = -1;
            this._counteractive = false;    
            this.startTicker();
         }
    
         start() {
            this._counteractive = true;
            console.clear();
            console.log(`Started,_counteractive is ${this._counteractive}`)
         }
         pause() {
            this._counteractive = false;
         }
         reset() {
             this.pause()  
             this.counter = 0;
         }
         public get count() : number {
            return this.counter
         }
         private startTicker() { 
             if (this.secondsTimer$) {return}
             let self = this;
   
            this.secondsTimer$ = new Observable(observer => {
                let interval = setInterval(() => {
                    console.log(`Time: ${Date.Now()} interval triggered.  counteractive ${self._counteractive} counter: ${self.counter}`)
                    if (self._counteractive) {
                        self.counter = self.counter + 1;
                        observer.next(self.counter)
                    }
                },1000);
                return function unsubscribe() {clearInterval(interval);
                }
            })
         }
    }

这是我正在运行的测试:

fit('starts counting seconds when start is called',async ()=>{
        console.log("starrt test")
        let controller = new CountDownTimerController();
        expect(controller.count).toBe(-1,"Should be initialized to -1");
        expect(controller.counteractive).toBeFalse;
        controller.start(); 
        expect(controller.counteractive).toBeTrue
        console.log(`Time: ${Date.Now()} controller started`)
        await utils.sleep(2000);  //WAIT FOR TWO TICKS OF SetInterval
        expect(controller.counteractive).toBeTrue();
        console.log(`Time: ${Date.Now()} Waited 2 seconds`)
        console.log(`Counter: ${controller.count}`)
 --->   expect(controller.count).toBeGreaterThanorEqual(1,`Ticker should be 1 or more at time ${Date.Now()}` )
        //FAILS ON THE PRECEDING LINE
       console.log("end test")
    });

如果感兴趣,这里是 utils.sleep 实现:

 export const sleep = (ms: number) => {
    return new Promise(resolve => setTimeout(resolve,ms))
}
 

这是控制台输出

Started,_counteractive is true count-down-timer-controller.spec.ts:37 
Time: 1625597279827 controller started count-down-timer-controller.spec.ts:40 
Time: 1625597281829 Waited 2 seconds count-down-timer-controller.spec.ts:41 
Counter: -1 count-down-timer-controller.spec.ts:44 
end test
debug.js:15 Failed CountDownTimerController starts counting seconds when start is called
debug.js:21 Error: Expected -1 to be greater than or equal 2,'Ticker should be 1 or more at time 1625597281829'.
    at <Jasmine>
    at count-down-timer-controller.spec.ts:42
    at <Jasmine>
    at fulfilled (tslib.es6.js:71)
debug.js:6 Skipped 27 tests

解决方法

您从未订阅可观察对象 (this.secondsTimer$),因此从未创建/触发间隔。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...