Caio Costa
12/29/2021, 10:09 PMMartin Rajniak
12/29/2021, 11:06 PMrunInBackgroud
extension )Caio Costa
12/29/2021, 11:13 PMCaio Costa
12/29/2021, 11:29 PMNick Allen
12/29/2021, 11:57 PMrunCurrent()
before you verify, assuming your background code is using the test dispatcher.Caio Costa
12/29/2021, 11:57 PMjava.lang.AssertionError: expected:<Toronto> but was:<null>
at org.junit.Assert.fail(Assert.java:89)
at org.junit.Assert.failNotEquals(Assert.java:835)
at org.junit.Assert.assertEquals(Assert.java:120)
at org.junit.Assert.assertEquals(Assert.java:146)
at com.project.weatherreport.WeatherViewModelTest$checkIfASuccessfulCallAlreadyBeenMade$1.invokeSuspend(WeatherViewModelTest.kt:79)
at com.project.weatherreport.WeatherViewModelTest$checkIfASuccessfulCallAlreadyBeenMade$1.invoke(WeatherViewModelTest.kt)
at com.project.weatherreport.WeatherViewModelTest$checkIfASuccessfulCallAlreadyBeenMade$1.invoke(WeatherViewModelTest.kt)
at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTestCoroutine$2.invokeSuspend(TestBuilders.kt:208)
at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTestCoroutine$2.invoke(TestBuilders.kt)
at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTestCoroutine$2.invoke(TestBuilders.kt)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startCoroutineUndispatched(Undispatched.kt:55)
at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:112)
at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126)
at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt.runTestCoroutine(TestBuilders.kt:207)
at kotlinx.coroutines.test.TestBuildersKt.runTestCoroutine(Unknown Source)
at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTest$1$1.invokeSuspend(TestBuilders.kt:167)
at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTest$1$1.invoke(TestBuilders.kt)
at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt$runTest$1$1.invoke(TestBuilders.kt)
at kotlinx.coroutines.test.TestBuildersJvmKt$createTestResult$1.invokeSuspend(TestBuildersJvm.kt:13)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:279)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at kotlinx.coroutines.test.TestBuildersJvmKt.createTestResult(TestBuildersJvm.kt:12)
at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt.runTest(TestBuilders.kt:166)
at kotlinx.coroutines.test.TestBuildersKt.runTest(Unknown Source)
at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt.runTest(TestBuilders.kt:154)
at kotlinx.coroutines.test.TestBuildersKt.runTest(Unknown Source)
at kotlinx.coroutines.test.TestBuildersKt__TestBuildersKt.runTest$default(TestBuilders.kt:147)
at kotlinx.coroutines.test.TestBuildersKt.runTest$default(Unknown Source)
at com.project.weatherreport.WeatherViewModelTest.checkIfASuccessfulCallAlreadyBeenMade(WeatherViewModelTest.kt:72)
Caio Costa
12/29/2021, 11:58 PMCaio Costa
12/30/2021, 12:22 AMCaio Costa
12/30/2021, 12:22 AMNick Allen
12/30/2021, 12:31 AMviewModel.viewModelScope.coroutineContext.job.children.forEach { it.join() }
Caio Costa
12/30/2021, 1:02 AMNick Allen
12/30/2021, 1:36 AMrunTaskOnBackground
and getWeatherInfo
to return the Job
from launch
and then join
on just that in the test.Caio Costa
12/30/2021, 3:23 AMA suggestion: modify runTaskOnBackground and getWeatherInfo to return the Job from launch and then join on just that in the test.
Gotcha, Tks 👍Eugen Martynov
12/30/2021, 8:26 AMEugen Martynov
12/30/2021, 9:28 AMEugen Martynov
12/30/2021, 9:45 AMEugen Martynov
12/30/2021, 10:41 AMtestScheduler.advanceUntilIdle()
and tests becomes greenJoffrey
12/30/2021, 11:04 AMrunBlockingTest
to runTest
, keep in mind that advanceTimeBy
changed semantics, and now it doesn't run the tasks that are exactly scheduled at the final time anymore. You should add runCurrent()
after advanceTimeBy
if you want the former behaviour. Using advanceUntilIdle
also works, but it's not equivalent (it will run also later tasks as long as some are scheduled).Martin Rajniak
12/30/2021, 7:12 PMTestScope
should work.Martin Rajniak
12/30/2021, 7:13 PMCaio Costa
12/30/2021, 7:16 PMInjecting TestScope should work.
Indeed. I'd rather not to expose Job but I've tried almost anything you can imagine including injecting both scopes and dispatchers and the only thing that made my test pass was expose the Coroutine JobCaio Costa
12/30/2021, 7:17 PMMartin Rajniak
12/30/2021, 7:48 PMLiveData
- I am used to using StateFlow
now.
IMHO, this problem is this one (nice write-up):
https://medium.com/androiddevelopers/unit-testing-livedata-and-other-common-observability-problems-bb477262eb04
Based on the article - this solution works:
https://github.com/caiodev/Weather/pull/1Martin Rajniak
12/30/2021, 7:49 PMandroidTest
)Caio Costa
12/30/2021, 7:53 PMNick Allen
12/30/2021, 8:07 PMcallbackExecutor { it.run() }
(executor that runs in place) to the Retrofit builder then I think that would remove the issue.Nick Allen
12/30/2021, 8:13 PMCaio Costa
12/30/2021, 8:32 PMCaio Costa
12/30/2021, 8:37 PMMartin Rajniak
12/30/2021, 8:54 PMfirst
does the trick for StateFlow
https://github.com/MartinRajniak/CatViewerDemo/blob/main/shared/src/commonTest/kotlin/eu/rajniak/cat/CatsTest.kt#L81