Mockito模拟Realm后实际close()方法仍执行引发线程异常问题咨询
解决Mockito模拟Realm时close()方法触发线程异常的问题
首先明确:Mockito是可以模拟Realm的,你的问题出在Realm核心类是final类,默认情况下Mockito无法直接模拟final方法,导致调用close()时实际执行了真实的Realm方法,从而触发线程异常。
为什么会出现这个问题?
Realm的Realm类被设计为final类,而Mockito默认不支持模拟final方法/类——当你尝试用Mockito.mock(Realm.class)创建模拟对象时,Mockito生成的是一个“伪模拟”,对于final方法(比如close()),它会直接调用真实的方法逻辑,而非你期望的模拟行为。这就导致即使你模拟了Realm,close()还是会执行真实的关闭逻辑,而模拟出来的Realm实例并没有在正确的线程上创建,自然抛出IllegalStateException。
解决方案:开启Mockito对final类的支持
不需要引入PowerMock,只需要简单配置就能让Mockito支持模拟final类:
- 在测试资源目录下创建路径:
src/test/resources/mockito-extensions - 在该目录下新建名为
org.mockito.plugins.MockMaker的文件 - 文件内容仅需一行:
mock-maker-inline
这个配置会启用Mockito的内联模拟引擎,让它能够处理final类和方法。
正确模拟Realm的close()方法
配置完成后,你就可以正常模拟Realm,并指定close()的行为了:
// 创建模拟的Realm实例 Realm mockRealm = Mockito.mock(Realm.class); // 让close()方法不执行任何实际逻辑 Mockito.doNothing().when(mockRealm).close(); // 将模拟实例注入到你的业务类中(假设save()方法依赖Realm) YourDataRepository repository = new YourDataRepository(mockRealm); repository.save(yourRealmModel); // 验证close()方法确实被调用了(可选) Mockito.verify(mockRealm, Mockito.times(1)).close();
另一种替代方案:使用Realm内存数据库
如果你不想修改Mockito配置,也可以用Realm提供的内存数据库测试,使用真实的Realm实例但数据不会持久化,线程问题也更容易控制:
// 创建内存版Realm配置 RealmConfiguration config = new RealmConfiguration.Builder() .inMemory() .name("test-realm") .build(); // 在当前线程创建Realm实例 Realm realm = Realm.getInstance(config); // 注入到业务类中执行save() YourDataRepository repository = new YourDataRepository(realm); repository.save(yourRealmModel); // 正常关闭,不会有线程问题 realm.close();
这个方案适合需要测试真实Realm操作逻辑的场景,而非仅模拟依赖。
内容的提问来源于stack exchange,提问作者Sebastian
相关产品推荐
相关产品推荐

