J'ai un problème avec le test d'une base de données Room: lorsque je lance le test, j'obtiens cette exception:
Java.lang.RuntimeException: cannot find implementation for database.TicketDatabase. TicketDatabase_Impl does not exist
at Android.Arch.persistence.room.Room.getGeneratedImplementation(Room.Java:92)
at Android.Arch.persistence.room.RoomDatabase$Builder.build(RoomDatabase.Java:454)
at com.sw.ing.gestionescontrini.DatabaseTest.setDatabase(DatabaseTest.Java:36)
at Java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.Java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.Java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.Java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.Java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.Java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.Java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.Java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.Java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.Java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.Java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.Java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.Java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.Java:363)
at org.junit.runners.Suite.runChild(Suite.Java:128)
at org.junit.runners.Suite.runChild(Suite.Java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.Java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.Java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.Java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.Java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.Java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.Java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.Java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.Java:115)
at Android.support.test.internal.runner.TestExecutor.execute(TestExecutor.Java:59)
at Android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.Java:262)
at Android.app.Instrumentation$InstrumentationThread.run(Instrumentation.Java:1886)
Classe DatabaseTest:
public class DatabaseTest {
TicketDatabase database;
DAO ticketDAO;
@Before
public void setDatabase() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Context context = InstrumentationRegistry.getTargetContext();
database = Room.inMemoryDatabaseBuilder(context, TicketDatabase.class).build();
Method method = TicketDatabase.class.getDeclaredMethod("ticketDao()");
method.setAccessible(true);
ticketDAO = (DAO) method.invoke(database, null);
}
}
fichier de classement:
apply plugin: 'com.Android.application'
Android {
compileSdkVersion 26
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "com.sw.ing.gestionescontrini"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "Android.support.test.runner.AndroidJUnitRunner"
}
defaultConfig {
multiDexEnabled true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.Android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.Android.support', module: 'support-annotations'
})
compile 'com.Android.support:appcompat-v7:26.+'
compile 'com.Android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
annotationProcessor 'Android.Arch.lifecycle:compiler:1.0.0'
compile 'Android.Arch.persistence.room:rxjava2:1.0.0-rc1'
testCompile'Android.Arch.persistence.room:testing:1.0.0-rc1'
}
Je ne sais pas vraiment ce que cette implémentation devrait être, j'ai cherché une solution mais tout ce que j'ai trouvé ne fonctionne pas pour moi. Par exemple, beaucoup ont trouvé une solution en ajoutant kapt "Android.Arch.persistence.room ..." mais Gradle ne reconnaît pas "kapt".
kapt
est pour Kotlin.
Tout d'abord, ajoutez:
annotationProcessor "Android.Arch.persistence.room:compiler:1.0.0"
à votre dependencies
clôture.
Ensuite, mettez à niveau Android.Arch.persistence.room:rxjava2
et Android.Arch.persistence.room:testing
à 1.0.0
au lieu de 1.0.0-rc1
.
ref: https://developer.Android.com/jetpack/androidx/releases/room
pour Kotlin, remplacez le mot clé 'annotationProcessor' par 'kapt' dans le fichier Gradle.
kapt "Android.Arch.persistence.room:compiler:1.1.1"
et aussi ajouter en plus du fichier de dépendance
apply plugin: 'kotlin-kapt'
ref: https://developer.Android.com/jetpack/androidx/releases/room
Si vous utilisez Kotlin, ce code existe dans votre fichier in grade.
apply plugin: "kotlin-kapt"
// Room
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
Documentation: https://developer.Android.com/jetpack/androidx/releases/room
Je vois des gens ici (Vishu Bhardwaj et d'autres sur des questions similaires à StackOverflow) se plaignent de ce que la réponse acceptée ne fonctionne pas pour eux. Je pense qu’il mérite de mentionner que j’avais un problème similaire dans un projet MULTI modules qui nécessitait une astuce autour de la réponse acceptée.
Dans mon projet multi-modules, les dépendances de la base de données de la pièce étaient principalement incluses dans un module de base et exportées à l'aide de la notation api appropriée, mais le code de la pièce était divisé en 2 modules différents. Projet compilé sans avertissement, mais Java.lang.RuntimeException: impossible de trouver l'implémentation pour la base de données ... a été déclenché à l'exécution.
Ceci a été corrigé en ajoutant
annotationProcessor "Android.Arch.persistence.room:compiler:$room_version"
dans TOUS les modules incluant le code associé à la salle.
Ce grade fonctionne bien. Notez le plugin kotlin-kapt au début. C'est crucial.
apply plugin: 'kotlin-kapt'
apply plugin: 'com.Android.application'
apply plugin: 'kotlin-Android'
apply plugin: 'kotlin-Android-extensions'
Android {
compileSdkVersion 28
defaultConfig {
applicationId "????"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "Android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.Android.support:appcompat-v7:28.0.0'
implementation 'com.Android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.Android.support.test:runner:1.0.2'
androidTestImplementation 'com.Android.support.test.espresso:espresso-core:3.0.2'
implementation 'Android.Arch.persistence.room:runtime:1.1.1'
kapt 'Android.Arch.persistence.room:compiler:1.1.1'
}
J'ai fait comme tout le monde dit dans la réponse ci-dessus toujours pas de chance.
Le problème de mon côté était que, je faisais une insertion sur le fil principal.
roomDatabase = Room.databaseBuilder(DexApplication.getInstance(),MyRoomDatabase.class,"db_name")
.fallbackToDestructiveMigration() // this is only for testing,
//migration will be added for release
.allowMainThreadQueries() // this solved the issue but remember that its For testing purpose only
.build();
Explication:
.allowMainThreadQueries()
vous permet d'exécuter des requêtes sur le thread principal. Mais gardez à l'esprit de le supprimer et d'implémenter RxJava, Live Data ou tout autre mécanisme de traitement en arrière-plan pour interroger la base de données. J'espère que ça aiderait.
Ajouter le plugin et la dépendance ci-dessous
appliquer le plugin: 'kotlin-kapt'
kapt "Android.Arch.persistence.room:compiler:1.1.1"