I've created a controller class for a countdown timer that is functioning correctly on the webpage, but I'm encountering issues with running my unit test. I am unsure if the problem lies in how I am executing the test or if there is an issue within the class itself.
Below is the code for the class being tested:
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);
}
})
}
}
The following is the test I am executing:
fit('Starts counting seconds when the start method is called', async ()=>{
console.log("Starting 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()}` )
//ISSUES WITH THE ABOVE LINE
console.log("Test completed")
});
If you are interested, below is the implementation for utils.sleep:
export const sleep = (ms: number) => {
return new Promise(resolve => setTimeout(resolve, ms))
}
Here is the output in the console:
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
Test completed
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