diff --git a/app/src/test/java/com/sadellie/unitto/CoroutinesTestUtils.kt b/app/src/test/java/com/sadellie/unitto/CoroutinesTestUtils.kt new file mode 100644 index 00000000..41a400e3 --- /dev/null +++ b/app/src/test/java/com/sadellie/unitto/CoroutinesTestUtils.kt @@ -0,0 +1,61 @@ +/* + * Unitto is a unit converter for Android + * Copyright (c) 2022 Elshan Agaev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sadellie.unitto + +import android.os.StrictMode +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestDispatcher +import kotlinx.coroutines.test.TestResult +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.test.setMain +import org.junit.Test +import org.junit.rules.TestWatcher +import org.junit.runner.Description + +@ExperimentalCoroutinesApi +class CoroutineTestRule(private val dispatcher: TestDispatcher = UnconfinedTestDispatcher()) : + TestWatcher() { + + override fun starting(description: Description) { + super.starting(description) + Dispatchers.setMain(dispatcher) + } + + override fun finished(description: Description) { + super.finished(description) + Dispatchers.resetMain() + } + +} + +@OptIn(ExperimentalCoroutinesApi::class) +@Test +fun testInViewModel(testBody: suspend TestScope.(CoroutineScope) -> Unit): TestResult = runTest { + // https://github.com/robolectric/robolectric/issues/6377#issuecomment-843779001 + StrictMode.enableDefaults() + val testDispatcher = UnconfinedTestDispatcher(testScheduler) + Dispatchers.setMain(testDispatcher) + testBody(CoroutineScope(testDispatcher)) + Dispatchers.resetMain() +} diff --git a/app/src/test/java/com/sadellie/unitto/screens/MainViewModelTest.kt b/app/src/test/java/com/sadellie/unitto/screens/MainViewModelTest.kt index 2d30c6ae..da2f710f 100644 --- a/app/src/test/java/com/sadellie/unitto/screens/MainViewModelTest.kt +++ b/app/src/test/java/com/sadellie/unitto/screens/MainViewModelTest.kt @@ -18,8 +18,8 @@ package com.sadellie.unitto.screens -import android.os.StrictMode import androidx.room.Room +import com.sadellie.unitto.CoroutineTestRule import com.sadellie.unitto.data.KEY_0 import com.sadellie.unitto.data.KEY_1 import com.sadellie.unitto.data.KEY_2 @@ -46,44 +46,21 @@ import com.sadellie.unitto.data.units.AllUnitsRepository import com.sadellie.unitto.data.units.database.MyBasedUnitDatabase import com.sadellie.unitto.data.units.database.MyBasedUnitsRepository import com.sadellie.unitto.screens.main.MainViewModel -import kotlinx.coroutines.CoroutineScope +import com.sadellie.unitto.testInViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.test.TestDispatcher -import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.resetMain -import kotlinx.coroutines.test.runTest -import kotlinx.coroutines.test.setMain import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Rule import org.junit.Test -import org.junit.rules.TestWatcher -import org.junit.runner.Description import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config -@ExperimentalCoroutinesApi -class CoroutineTestRule(private val dispatcher: TestDispatcher = UnconfinedTestDispatcher()) : - TestWatcher() { - - override fun starting(description: Description) { - super.starting(description) - Dispatchers.setMain(dispatcher) - } - - override fun finished(description: Description) { - super.finished(description) - Dispatchers.resetMain() - } - -} - - @OptIn(ExperimentalCoroutinesApi::class) @Config(manifest = Config.NONE) @RunWith(RobolectricTestRunner::class) @@ -112,12 +89,8 @@ class MainViewModelTest { } @Test - fun processInputTest() = runTest { - // https://github.com/robolectric/robolectric/issues/6377#issuecomment-843779001 - StrictMode.enableDefaults() - val testDispatcher = UnconfinedTestDispatcher(testScheduler) - Dispatchers.setMain(testDispatcher) - viewModel.mainFlow.launchIn(CoroutineScope(testDispatcher)) + fun processInputTest() = testInViewModel { coroutineScope -> + viewModel.mainFlow.launchIn(coroutineScope) /** * For simplicity comments will have structure: @@ -360,12 +333,8 @@ class MainViewModelTest { } @Test - fun deleteSymbolTest() = runTest { - // https://github.com/robolectric/robolectric/issues/6377#issuecomment-843779001 - StrictMode.enableDefaults() - val testDispatcher = UnconfinedTestDispatcher(testScheduler) - Dispatchers.setMain(testDispatcher) - viewModel.mainFlow.launchIn(CoroutineScope(testDispatcher)) + fun deleteSymbolTest() = testInViewModel { coroutineScope -> + viewModel.mainFlow.launchIn(coroutineScope) listOf( KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0, @@ -391,4 +360,4 @@ class MainViewModelTest { Dispatchers.resetMain() } -} \ No newline at end of file +}