test(local): use ContextWrapper not mockk<Context> in provisioner test
DatabaseProvisionerInstrumentedTest crashed in @Before setUp() on API 31/32 with ArrayIndexOutOfBoundsException (length=0; index=0), passing on API 29. The stack shows the throw is entirely in the test harness: mockk<Context>() -> MockK JvmMockFactoryHelper.isKotlinInline -> kotlin-reflect ReflectJavaMember.getValueParameters, which indexes parameterAnnotations[0] on an empty array. Mocking android.content.Context makes MockK walk the whole framework class with kotlin-reflect, and on Android 12/12L ART returns a parameter-annotation array shorter than the parameter-type array for some Context method, so kotlin-reflect throws. Production DatabaseProvisioner/DatabaseEncryption code never runs. Replace the mockk<Context> with a real ContextWrapper(appContext) that overrides getDatabasePath to route the cache file to the test DB and delegates everything else, sidestepping the framework-class reflection walk. Verified 3/3 pass on the dev36 GMD emulator; API 31/32 left to CI (images not installed locally). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+10
-2
@@ -2,6 +2,7 @@
|
||||
package org.libremail.data.local
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
@@ -57,12 +58,19 @@ class DatabaseProvisionerInstrumentedTest {
|
||||
private val keyStore = mockk<DatabaseKeyStore>()
|
||||
private val settingsRepository = mockk<SettingsRepository>()
|
||||
private val migrator = mockk<AccountDataMigrator>()
|
||||
private val context = mockk<Context>()
|
||||
|
||||
// A real ContextWrapper, NOT a mockk<Context>: mocking android.content.Context makes MockK walk the
|
||||
// whole framework class with kotlin-reflect (isKotlinInline), which trips an ART parameter-annotation
|
||||
// length mismatch and throws ArrayIndexOutOfBoundsException on API 31/32 (it passes on API 29). The
|
||||
// wrapper routes the provisioner's cache lookup to the test DB and delegates everything else.
|
||||
private val context: Context = object : ContextWrapper(appContext) {
|
||||
override fun getDatabasePath(name: String): File =
|
||||
if (name == DatabaseFiles.NAME) dbFile else super.getDatabasePath(name)
|
||||
}
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
clean()
|
||||
every { context.getDatabasePath(DatabaseFiles.NAME) } returns dbFile
|
||||
coEvery { keyStore.isClearPending() } returns false
|
||||
coEvery { keyStore.resolvePassphrase(any()) } returns passphrase
|
||||
coEvery { migrator.migrateIfNeeded() } just Runs
|
||||
|
||||
Reference in New Issue
Block a user