我正在运行 androidTest 仪器测试,我有一个方法可以使用 Room 从 DAO 对象返回 LiveData。
我是这样调用方法的:
val animal = roomDatabase.animalsDao().getAnimal(1)
animal.observeForever(mMockObserver)
assertNotNull(animal.value)
我使用 Mockito 来模拟观察者:
@Mock
private lateinit var mMockObserver = Observer<Animal>
这应该返回一个包含 ID 为 1 的 Animal 的 LiveData 实例,但它是 null。据我了解,为了让 LiveData 返回任何内容,必须有一个观察者。我是否设置不正确?
注意:如果我在 DAO 中更改 getAnimal() 的签名以直接返回 Animal 而不是 LiveData,那么它会起作用,所以我知道它与 LiveData 有关。
最佳答案
经过更多挖掘后,我发现了 Google 通过 GitHub 上的架构组件示例提供的实用方法。
public class LiveDataTestUtil {
/**
* Get the value from a LiveData object. We're waiting for LiveData to emit, for 2 seconds.
* Once we got a notification via onChanged, we stop observing.
*/
public static <T> T getValue(final LiveData<T> liveData) throws InterruptedException {
final Object[] data = new Object[1];
final CountDownLatch latch = new CountDownLatch(1);
Observer<T> observer = new Observer<T>() {
@Override
public void onChanged(@Nullable T o) {
data[0] = o;
latch.countDown();
liveData.removeObserver(this);
}
};
liveData.observeForever(observer);
latch.await(2, TimeUnit.SECONDS);
//noinspection unchecked
return (T) data[0];
}
}
这允许您传递 LiveData 实例并取回它持有的值。
更新(JUnit 4):
您还可以使用 InstantTaskExecutorRule结合 observeForever测试您的 LiveData。在 Kotlin 中,您在测试类的顶部设置 @get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule()
以确保同步处理 LiveData,然后在您的测试用例中 myLiveData.observeForever {/* Do事件发出时发生的事情 */
以获取 LiveData 值。
更新(JUnit 5)
如果您使用的是 JUnit5,那么您可以使用此扩展来代替上面更新 (JUnit4) 中解释的规则。
class InstantTaskExecutorExtension : BeforeEachCallback, AfterEachCallback {
override fun beforeEach(context: ExtensionContext?) {
ArchTaskExecutor.getInstance().setDelegate(object : TaskExecutor() {
override fun executeOnDiskIO(runnable: Runnable) {
runnable.run()
}
override fun postToMainThread(runnable: Runnable) {
runnable.run()
}
override fun isMainThread(): Boolean {
return true
}
})
}
override fun afterEach(context: ExtensionContext?) {
ArchTaskExecutor.getInstance().setDelegate(null)
}
}
通过像这样注释您的测试类来使用此扩展:
@ExtendWith(InstantTaskExecutorExtension::class)
class MyTestClass { ... }
如果您不熟悉扩展(它们取代了 JUnit 4 规则),您可以在此处找到其他文档:https://junit.org/junit5/docs/current/user-guide/#extensions
关于androidTest 中的 Android LiveData 返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48602979/