android - Android,Room 在使用 Robolectric 进行单元测试时失败
问题描述
我正在尝试为视图模型创建一些测试。
视图模型包括一个调用数据库的数据库实例化
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()
任何想法如何克服该异常?
我们实际上不需要以某种方式测试数据库,只需要该模型中包含的一些功能,所以一些避免错误的方法就足够了。
解决方案
Room 应该作为Android Instrumentation Test进行测试,而不是 JUnit 测试。
更新:
使用mockito模拟数据库和任何存储库。
使用 mockito 方法,例如:
- @Mock - 模拟注释以模拟全局和局部变量。
- mock - 在线启动类的模拟。
- when - 为模拟配置返回行为。
- verify - 在模拟及其方法上断言交互。
- times - 与 verify 一起使用来断言对模拟及其方法的调用次数。
- any - 一个参数匹配器,用于向模拟断言提供的值。
使用 Mockito,例如。我不知道你的代码是如何工作的,我做了一些假设,比如 Call.class 的存在以及你需要什么模拟:
@Mock private CallRoomDatabase database;
@Mock private CRoomDatabase cRoomDatabase;
@Mock private CDao cDao;
private MyClass myClass;
@Before
public void setUp() {
// initiate all globally defined mocks annotated with @Mock
initMocks(this);
// Setup our expected behaviour from the mock
when(database.getDatabase()).thenReturn(cRoomDatabase);
myClass = new myClass(database, cDao);
}
@Test
public void givenSomeTest_whenCallingGetCall_thenInsertNewCall() {
// Setup our expected behaviour from the mock
when(cDao.getCall()).thenReturn(mock(Call.class));
// do test
// assert mock interaction with arguments and number of expected calls
verify(cDao, times(1)).insertCall(any(mock(Call.class)))
}
推荐阅读
- java - 尝试检测自创的死锁
- c# - .NET Core for Linux with dockers - 创建 docker 镜像
- electron - 在 electronjs 应用启动时通过 sequelize 初始化数据库
- background - 当应用程序进入前台时,OpenTok 发布者的视图变黑
- excel - Excel VBA 2 输入文件,每个文件都以不同的格式打开和复制,而不是相同的格式
- javascript - 与聚合物 lit-element 0.6.2 结合不起作用
- amazon-web-services - 具有步进扩展的 AWS 计划自动扩展
- javascript - “AbstractControl”类型上不存在属性“控件”。角 7
- ruby-on-rails - rails验证错误嵌套对象未定义方法...对于nil:NilClass
- mysql - 按星期几和一天中的时间过滤日期