我正在尝试为我的 Android 应用程序编写一个与云服务通信的测试。 理论上测试的流程应该是这样的:
我正在尝试使用 Espresso 的
IdlingResource
类来完成此任务,但它没有按预期工作。这是我到目前为止所拥有的
我的测试:
@RunWith(AndroidJUnit4.class)
public class CloudManagerTest {
FirebaseOperationIdlingResource mIdlingResource;
@Before
public void setup() {
mIdlingResource = new FirebaseOperationIdlingResource();
Espresso.registerIdlingResources(mIdlingResource);
}
@Test
public void testAsyncOperation() {
Cloud.CLOUD_MANAGER.getDatabase().getCategories(new OperationResult<List<Category>>() {
@Override
public void onResult(boolean success, List<Category> result) {
mIdlingResource.onOperationEnded();
assertTrue(success);
assertNotNull(result);
}
});
mIdlingResource.onOperationStarted();
}
}
FirebaseOperationIdlingResource
public class FirebaseOperationIdlingResource implements IdlingResource {
private boolean idleNow = true;
private ResourceCallback callback;
@Override
public String getName() {
return String.valueOf(System.currentTimeMillis());
}
public void onOperationStarted() {
idleNow = false;
}
public void onOperationEnded() {
idleNow = true;
if (callback != null) {
callback.onTransitionToIdle();
}
}
@Override
public boolean isIdleNow() {
synchronized (this) {
return idleNow;
}
}
@Override
public void registerIdleTransitionCallback(ResourceCallback callback) {
this.callback = callback;
}}
与 Espresso 的视图匹配器一起使用时,测试正确执行,活动等待,然后检查结果。
但是,普通的 JUNIT4 断言方法会被忽略,并且 JUnit 不会等待我的云操作完成。
是否有可能
IdlingResource
仅适用于浓缩咖啡方法?还是我做错了什么?
我使用 Awaitility 来做类似的事情。
它有一个非常好的指南,这是基本思想:
无论您需要在哪里等待:
await().until(newUserIsAdded());
其他地方:
private Callable<Boolean> newUserIsAdded() {
return new Callable<Boolean>() {
public Boolean call() throws Exception {
return userRepository.size() == 1; // The condition that must be fulfilled
}
};
}
我认为这个示例与您正在做的非常相似,因此将异步操作的结果保存到一个字段中,并在
call()
方法中检查它。
Junit 不会等待异步任务完成。您可以使用 CountDownLatch 来阻塞线程,直到收到服务器的响应或超时。
倒计时锁存器是一个简单而优雅的解决方案,不需要外部库。它还可以帮助您专注于要测试的实际逻辑,而不是过度设计异步等待或等待响应
void testBackgroundJob() {
CountDownLatch latch = new CountDownLatch(1);
//Do your async job
Service.doSomething(new Callback() {
@Override
public void onResponse(){
ACTUAL_RESULT = SUCCESS;
latch.countDown(); // notify the count down latch
// assertEquals(..
}
});
//Wait for api response async
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
assertEquals(expectedResult, ACTUAL_RESULT);
}