我正在尝试为一个视图模型创建一些测试。
该视图模型包括一个数据库实例化,调用了一个数据库:
CallRoomDatabase db = CallRoomDatabase.getDatabase(application);
其中getDatabase需要一个Dao()的实例。
@Database(entities = {CallEntity.class}, version = 1)
public abstract class CallRoomDatabase extends RoomDatabase {
public abstract CDao cDao();
// marking the instance as volatile to ensure atomic access to the variable
private static volatile CRoomDatabase INSTANCE;
public static CRoomDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (CallRoomDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
CRoomDatabase.class, "database")
// Wipes and rebuilds instead of migrating if no Migration object.
// Migration is not part of this codelab.
.fallbackToDestructiveMigration()
.addCallback(sRoomDatabaseCallback)
.build();
}
}
}
return INSTANCE;
}
然而,在尝试在测试中实例化该模型时,我在上面的.build()
代码处遇到了一个错误。
java.lang.NullPointerException
at androidx.room.Room.getGeneratedImplementation(Room.java:79)
at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:952)
at com.s.o.dbutils.CRoomDatabase.getDatabase(CRoomDatabase.java:32)
at com.s.o.viewmodels.CViewModelTest.checkForNuTest(CViewModelTest.kt:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
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.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.powermock.modules.junit4.rule.PowerMockStatement$1.run(PowerMockRule.java:83)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
在
RoomDatabase.java
。 T db = Room.getGeneratedImplementation(mDatabaseClass, DB_IMPL_SUFFIX);
在 Room.java
中,klass
为 null
static <T, C> T getGeneratedImplementation(Class<C> klass, String suffix) {
我尝试在测试中根本不使用模型,只使用以下方法实例化数据库:
val db = CRoomDatabase.getDatabase(ApplicationProvider.getApplicationContext())
仍然在相同的.build()
处发生错误。
有任何想法如何避免这个异常吗?
实际上我们并不需要对数据库进行测试,只需要在该模型中包含一些函数,因此只需找到一种方法来避免错误即可。
MockClassLoader
中。有趣的是,当你在测试类中定义一个成员变量(lateinit val db: CallRoomDatabase
)时,即使该变量没有分配任何对象,也不会出现错误。 - MinseongPark