Unit testing swift timer function using nimble

1.1k Views Asked by At

I am using Quick, Nimble, and RxSwift.

My goal is to write unit test that test some function with Timer on it which will be executed repeatedly after some time interval.

My pseudo class

final class TestingTimerClass {
    let counter: BehaviorRelay<Int> = BehaviorRelay<Int>(value: 0)
    private var timer: Timer?

    ....

    func startTimer() {

        timer = Timer.scheduledTimer(
            timeInterval: 8,
            target: self as Any,
            selector: #selector(self.executeFunction),
            userInfo: nil,
            repeats: true
        )
    }

    @objc private func executeFunction() {
        let currentValue = counter.value
        counter.accept(currentValue + 1)
    }
}

My testing class

class TestingTimerClass: QuickSpec {

    override func spec() {
        var testingClass: TestingTimerClass!

        describe("executing") {

            context("startTimer()") {

                beforeEach {
                    testingClass = TestingTimerClass()
                }

                afterEach {
                    testingClass = nil
                }

                it("should update counter value after a period of time") {

                    testingClass.startTimer()
                    expect(testingClass.counter.value).toEventually(equal(1), timeout: TimeInterval(9), pollInterval: TimeInterval(2), description: nil)
                }
            }
        }
    }
}

I expect that executeFunction() will be called after 8 second, however it is never called and my test suite is failed.

Any idea what went wrong?

1

There are 1 best solutions below

0
Cruz On

You should reduce your Nimble polling interval because your polling is occur every per 2 seconds to compare your testing class counter value to expected value '1' is per every 2 seconds.

expect for 9 seconds(timeout) but your last polling ended after exactly 8 seconds polling.

Increase your timeout more than 10 seconds or Reduce your polling interval to compare expected value before timeout.

In advance

You can reduce your totally testing time by injecting time interval or using RxTest