mirror of
https://github.com/bitfireAT/davx5-ose.git
synced 2025-12-23 23:17:50 -05:00
Simplify running suspending tests (#1452)
* Move LoggerModule to di package and add TestLoggerModule * Remove main dispatcher injection and use runTest directly * Add verbose logging module for tests * Add test for UnifiedPushService.onUnregistered
This commit is contained in:
@@ -9,8 +9,12 @@ import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.test.runner.AndroidJUnitRunner
|
||||
import at.bitfire.davdroid.di.TestCoroutineDispatchersModule
|
||||
import at.bitfire.davdroid.sync.SyncAdapterService
|
||||
import dagger.hilt.android.testing.HiltTestApplication
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.setMain
|
||||
|
||||
@Suppress("unused")
|
||||
class HiltTestRunner : AndroidJUnitRunner() {
|
||||
@@ -18,6 +22,7 @@ class HiltTestRunner : AndroidJUnitRunner() {
|
||||
override fun newApplication(cl: ClassLoader, name: String, context: Context): Application =
|
||||
super.newApplication(cl, HiltTestApplication::class.java.name, context)
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
override fun onCreate(arguments: Bundle?) {
|
||||
super.onCreate(arguments)
|
||||
|
||||
@@ -27,6 +32,9 @@ class HiltTestRunner : AndroidJUnitRunner() {
|
||||
|
||||
// disable sync adapters
|
||||
SyncAdapterService.syncActive.set(false)
|
||||
|
||||
// set main dispatcher for tests (especially runTest)
|
||||
Dispatchers.setMain(TestCoroutineDispatchersModule.standardTestDispatcher)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
package at.bitfire.davdroid.di
|
||||
|
||||
import at.bitfire.davdroid.di.TestCoroutineDispatchersModule.standardTestDispatcher
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
@@ -13,8 +14,10 @@ import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestCoroutineScheduler
|
||||
|
||||
/**
|
||||
* If you run tests that switch context to one of these dispatchers, use `runTest(mainDispatcher)`
|
||||
* with `mainDispatcher` being an injected [MainDispatcher] instead of plain `runTest`.
|
||||
* Provides test dispatchers to be injected instead of the normal ones.
|
||||
*
|
||||
* The [standardTestDispatcher] is set as main dispatcher in [at.bitfire.davdroid.HiltTestRunner],
|
||||
* so that tests can just use [kotlinx.coroutines.test.runTest] without providing [standardTestDispatcher].
|
||||
*/
|
||||
@Module
|
||||
@TestInstallIn(
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.di
|
||||
|
||||
import at.bitfire.davdroid.log.LogcatHandler
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import dagger.hilt.testing.TestInstallIn
|
||||
import java.util.logging.Level
|
||||
import java.util.logging.Logger
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Module that provides verbose logging for tests.
|
||||
*/
|
||||
@TestInstallIn(
|
||||
components = [SingletonComponent::class],
|
||||
replaces = [LoggerModule::class]
|
||||
)
|
||||
@Module
|
||||
class TestLoggerModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun logger(): Logger = Logger.getGlobal().apply {
|
||||
level = Level.ALL
|
||||
addHandler(LogcatHandler())
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.IBinder
|
||||
import androidx.test.rule.ServiceTestRule
|
||||
import at.bitfire.davdroid.di.MainDispatcher
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.android.testing.BindValue
|
||||
import dagger.hilt.android.testing.HiltAndroidRule
|
||||
@@ -19,7 +18,6 @@ import io.mockk.every
|
||||
import io.mockk.impl.annotations.RelaxedMockK
|
||||
import io.mockk.junit4.MockKRule
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
import kotlinx.coroutines.test.runTest
|
||||
@@ -48,10 +46,6 @@ class UnifiedPushServiceTest {
|
||||
@ApplicationContext
|
||||
lateinit var context: Context
|
||||
|
||||
@Inject
|
||||
@MainDispatcher
|
||||
lateinit var mainDispatcher: CoroutineDispatcher
|
||||
|
||||
@RelaxedMockK
|
||||
@BindValue
|
||||
lateinit var pushRegistrationManager: PushRegistrationManager
|
||||
@@ -70,7 +64,7 @@ class UnifiedPushServiceTest {
|
||||
|
||||
|
||||
@Test
|
||||
fun testOnNewEndpoint() = runTest(mainDispatcher) {
|
||||
fun testOnNewEndpoint() = runTest {
|
||||
val endpoint = mockk<PushEndpoint> {
|
||||
every { url } returns "https://example.com/12"
|
||||
}
|
||||
@@ -84,7 +78,7 @@ class UnifiedPushServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnRegistrationFailed() = runTest(mainDispatcher) {
|
||||
fun testOnRegistrationFailed() = runTest {
|
||||
unifiedPushService.onRegistrationFailed(FailedReason.INTERNAL_ERROR, "34")
|
||||
|
||||
advanceUntilIdle()
|
||||
@@ -95,8 +89,8 @@ class UnifiedPushServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnUnregistered() = runTest(mainDispatcher) {
|
||||
unifiedPushService.onRegistrationFailed(FailedReason.INTERNAL_ERROR, "45")
|
||||
fun testOnUnregistered() = runTest {
|
||||
unifiedPushService.onUnregistered("45")
|
||||
|
||||
advanceUntilIdle()
|
||||
coVerify {
|
||||
|
||||
@@ -6,7 +6,6 @@ package at.bitfire.davdroid.ui
|
||||
|
||||
import at.bitfire.davdroid.db.Collection
|
||||
import at.bitfire.davdroid.db.Service
|
||||
import at.bitfire.davdroid.di.MainDispatcher
|
||||
import at.bitfire.davdroid.push.PushRegistrationManager
|
||||
import at.bitfire.davdroid.repository.DavCollectionRepository
|
||||
import at.bitfire.davdroid.repository.DavServiceRepository
|
||||
@@ -17,7 +16,6 @@ import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.impl.annotations.RelaxedMockK
|
||||
import io.mockk.junit4.MockKRule
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
import kotlinx.coroutines.test.runTest
|
||||
@@ -48,10 +46,6 @@ class CollectionSelectedUseCaseTest {
|
||||
@Inject
|
||||
lateinit var collectionRepository: DavCollectionRepository
|
||||
|
||||
@Inject
|
||||
@MainDispatcher
|
||||
lateinit var mainDispatcher: CoroutineDispatcher
|
||||
|
||||
val service = Service(
|
||||
id = 1,
|
||||
type = Service.Companion.TYPE_CALDAV,
|
||||
@@ -87,7 +81,7 @@ class CollectionSelectedUseCaseTest {
|
||||
|
||||
|
||||
@Test
|
||||
fun testHandleWithDelay() = runTest(mainDispatcher) {
|
||||
fun testHandleWithDelay() = runTest {
|
||||
useCase.handleWithDelay(collectionId = collection.id)
|
||||
|
||||
advanceUntilIdle()
|
||||
|
||||
@@ -9,13 +9,11 @@ import android.security.NetworkSecurityPolicy
|
||||
import at.bitfire.davdroid.db.AppDatabase
|
||||
import at.bitfire.davdroid.db.WebDavDocument
|
||||
import at.bitfire.davdroid.db.WebDavMount
|
||||
import at.bitfire.davdroid.di.MainDispatcher
|
||||
import at.bitfire.davdroid.network.HttpClient
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.android.testing.HiltAndroidRule
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import io.mockk.junit4.MockKRule
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import okhttp3.CookieJar
|
||||
import okhttp3.mockwebserver.Dispatcher
|
||||
@@ -52,10 +50,6 @@ class DavDocumentsProviderTest {
|
||||
|
||||
@Inject
|
||||
lateinit var db: AppDatabase
|
||||
|
||||
@Inject
|
||||
@MainDispatcher
|
||||
lateinit var mainDispatcher: CoroutineDispatcher
|
||||
|
||||
@Inject
|
||||
lateinit var testDispatcher: TestDispatcher
|
||||
@@ -92,7 +86,7 @@ class DavDocumentsProviderTest {
|
||||
|
||||
|
||||
@Test
|
||||
fun testDoQueryChildren_insert() = runTest(mainDispatcher) {
|
||||
fun testDoQueryChildren_insert() = runTest {
|
||||
// Create parent and root in database
|
||||
val id = db.webDavMountDao().insert(WebDavMount(0, "Cat food storage", server.url(PATH_WEBDAV_ROOT)))
|
||||
val webDavMount = db.webDavMountDao().getById(id)
|
||||
@@ -113,7 +107,7 @@ class DavDocumentsProviderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDoQueryChildren_update() = runTest(mainDispatcher) {
|
||||
fun testDoQueryChildren_update() = runTest {
|
||||
// Create parent and root in database
|
||||
val mountId = db.webDavMountDao().insert(WebDavMount(0, "Cat food storage", server.url(PATH_WEBDAV_ROOT)))
|
||||
val webDavMount = db.webDavMountDao().getById(mountId)
|
||||
@@ -149,7 +143,7 @@ class DavDocumentsProviderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDoQueryChildren_delete() = runTest(mainDispatcher) {
|
||||
fun testDoQueryChildren_delete() = runTest {
|
||||
// Create parent and root in database
|
||||
val mountId = db.webDavMountDao().insert(WebDavMount(0, "Cat food storage", server.url(PATH_WEBDAV_ROOT)))
|
||||
val webDavMount = db.webDavMountDao().getById(mountId)
|
||||
@@ -173,7 +167,7 @@ class DavDocumentsProviderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDoQueryChildren_updateTwoDirectoriesSimultaneously() = runTest(mainDispatcher) {
|
||||
fun testDoQueryChildren_updateTwoDirectoriesSimultaneously() = runTest {
|
||||
// Create root in database
|
||||
val mountId = db.webDavMountDao().insert(WebDavMount(0, "Cat food storage", server.url(PATH_WEBDAV_ROOT)))
|
||||
val webDavMount = db.webDavMountDao().getById(mountId)
|
||||
|
||||
@@ -4,10 +4,8 @@
|
||||
|
||||
package at.bitfire.davdroid.webdav
|
||||
|
||||
import at.bitfire.davdroid.di.MainDispatcher
|
||||
import dagger.hilt.android.testing.HiltAndroidRule
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import okhttp3.mockwebserver.MockResponse
|
||||
import okhttp3.mockwebserver.MockWebServer
|
||||
@@ -24,10 +22,6 @@ class WebDavMountRepositoryTest {
|
||||
@get:Rule
|
||||
val hiltRule = HiltAndroidRule(this)
|
||||
|
||||
@Inject
|
||||
@MainDispatcher
|
||||
lateinit var mainDispatcher: CoroutineDispatcher
|
||||
|
||||
@Inject
|
||||
lateinit var repository: WebDavMountRepository
|
||||
|
||||
@@ -40,13 +34,13 @@ class WebDavMountRepositoryTest {
|
||||
val url = web.url("/")
|
||||
|
||||
@Test
|
||||
fun testHasWebDav_NoDavHeader() = runTest(mainDispatcher) {
|
||||
fun testHasWebDav_NoDavHeader() = runTest {
|
||||
web.enqueue(MockResponse().setResponseCode(200))
|
||||
assertFalse(repository.hasWebDav(url, null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHasWebDav_DavClass1() = runTest(mainDispatcher) {
|
||||
fun testHasWebDav_DavClass1() = runTest {
|
||||
web.enqueue(MockResponse()
|
||||
.setResponseCode(200)
|
||||
.addHeader("DAV: 1"))
|
||||
@@ -54,7 +48,7 @@ class WebDavMountRepositoryTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHasWebDav_DavClass2() = runTest(mainDispatcher) {
|
||||
fun testHasWebDav_DavClass2() = runTest {
|
||||
web.enqueue(MockResponse()
|
||||
.setResponseCode(200)
|
||||
.addHeader("DAV: 1, 2"))
|
||||
@@ -62,7 +56,7 @@ class WebDavMountRepositoryTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHasWebDav_DavClass3() = runTest(mainDispatcher) {
|
||||
fun testHasWebDav_DavClass3() = runTest {
|
||||
web.enqueue(MockResponse()
|
||||
.setResponseCode(200)
|
||||
.addHeader("DAV: 1, 3"))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
|
||||
*/
|
||||
|
||||
package at.bitfire.davdroid.log
|
||||
package at.bitfire.davdroid.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
Reference in New Issue
Block a user