Kirill Zhukov
03/14/2025, 7:07 PMasClue
and withClue
but I'm not seeing the clue included in a stacktrace 🧵Kirill Zhukov
03/14/2025, 7:08 PMsuspend fun <ScreenT : Screen> ScreenPresenter<ScreenT>.test(
screen: ScreenT,
testTimeout: Duration = 10.seconds,
modelTimeout: Duration = 3.seconds,
validate: suspend ReceiveTurbine<ScreenModel>.(NavigatorMock) -> Unit,
) {
val navigator = NavigatorMock()
withTimeoutThrowing(testTimeout) {
val dispatcher = singleThreadedDispatcher()
val models = moleculeFlow(Immediate) { model(navigator, screen) }
.flowOn(dispatcher)
.onCompletion { dispatcher.cancel() }
.distinctUntilChanged()
models.test(modelTimeout) {
validate(navigator)
}
}
withClue("Unconsumed Navigator events") {
navigator.goToCalls.expectNoEvents()
navigator.exitCalls.expectNoEvents()
}
}
Kirill Zhukov
03/14/2025, 7:08 PMnavigator.goToCalls.expectNoEvents()
assert failsKirill Zhukov
03/14/2025, 7:08 PMEmil Kantis
03/14/2025, 9:58 PMexpectNoEvents
definition look like?Emil Kantis
03/14/2025, 10:30 PMAssertionError
s.. I think it can be fixed though. For now I think you could wrap it with shouldNotThrowAny { }
, i.e
withClue("Unconsumed Navigator events") {
shouldNotThrowAny {
navigator.goToCalls.expectNoEvents()
navigator.exitCalls.expectNoEvents()
}
}
Emil Kantis
03/14/2025, 10:39 PMI think it can be fixed thoughLooked into it a bit, and it seems a bit complicated.. 😕
Alex Kuznetsov
03/17/2025, 1:14 PMshouldNotThrowAny
should do it in 6.0, but not in 5.9.1Alex Kuznetsov
03/17/2025, 1:15 PMKirill Zhukov
03/17/2025, 5:56 PMshouldNotThrowAny
be an implementation detail of assertSoftly
?Alex Kuznetsov
03/17/2025, 5:58 PMKirill Zhukov
03/17/2025, 5:59 PMassertSoftly
couldn't just call shouldNotThrowAny
internally to achieve the effect of making sure all errors are wrapped softly?Alex Kuznetsov
03/17/2025, 6:03 PMassertSoftly
work, because it takes a collection of lambdas and executes them one at a time.
OTOH assertSoftly
takes only one parameter. so whatever is inside that lambda should not be throwing exceptions.