Cuckoo icon indicating copy to clipboard operation
Cuckoo copied to clipboard

Never returning async stubbing

Open jdanthinne opened this issue 8 months ago • 4 comments

I'm testing a timeout case in my test, and my stubbed service has this method func myMethod() async throws -> String.

When stubbing this method, I can use theReturn or thenThrow, but how to make my method never return?

I'm cheating in the following code by sleeping longer than the defined timeout then returning a value, but is there a cleaner way?

stub(mock) { stub in
    when(stub.myMethod()).then { _ in
        sleep(5)
        return ""
    }
}

jdanthinne avatar May 14 '25 13:05 jdanthinne

Hi, you mean to test a deadlock of some sort? I'm not sure there's a cleaner way to do this other than wait for the timeout.

MatyasKriz avatar Jun 11 '25 20:06 MatyasKriz

I mean to test if a timeout is correctly handled if a method gets longer than the tested timeout to finish, or never finishes. I'm fine with my cheat, but was just wondering if something like thenNeverReturns could be possible.

jdanthinne avatar Jun 12 '25 07:06 jdanthinne

In that case I think this might work for you. 🙂

extension StubFunctionThenTrait {
    @discardableResult
    func thenNeverReturn() -> Self {
        stub.appendAction(.callImplementation({ _ in sleep(9999999); fatalError() }))
        return self
    }
}

MatyasKriz avatar Jun 13 '25 06:06 MatyasKriz

Yes, why not? Or wouldn't be possible to add initial delay to current methods? If the delay is longer than the timeout, that would do the trick, and is nicer than fatalError. What do you think? I can make a PR if needed.

jdanthinne avatar Jun 14 '25 13:06 jdanthinne