[英]Mockito with Java async->sync converter
我有一个异步方法,正在使用倒数锁存器转换为同步方法。 我在不使用嘲笑的超时功能的情况下努力编写单元测试。 我不知道如何获取验证方法以等待异步方法调用:
public interface SyncExchangeService {
boolean placeOrder(Order order);
}
public interface ExchangeService {
void placeOrder(Order order, OrderCallback orderResponseCallback);
}
public interface OrderCallback {
public void onSuccess();
public void onFailure();
}
public class SyncExchangeServiceAdapter implements SyncExchangeService {
private ExchangeService exchangeService;
public SyncExchangeServiceAdapter(ExchangeService exchangeService) {
this.exchangeService = exchangeService;
}
@Override
public boolean placeOrder(Order order) {
final CountDownLatch countdownLatch=new CountDownLatch(1);
final AtomicBoolean result=new AtomicBoolean();
exchangeService.placeOrder(order, new OrderCallback() {
@Override
public void onSuccess() {
result.set(true);
countdownLatch.countDown();
}
@Override
public void onFailure(String rejectReason) {
result.set(false);
countdownLatch.countDown();
}
});
try {
countdownLatch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return result.get();
}
}
public class SyncExchangeServiceAdapterTest {
private ExchangeService mockExchange=mock(ExchangeService.class);
private SyncExchangeServiceAdapter adapter=new SyncExchangeServiceAdapter(mockExchange);
private Boolean response;
private ArgumentCaptor<Boolean> callback=CaptorArgumentCaptor.forClass(OrderCallback.class);
private CountDownLatch latch=new CountDownLatch(1);
@Test
public void testPlaceOrderWithSuccess() throws Exception {
final Order order=mock(Order.class);
Executors.newSingleThreadExecutor().submit(new Runnable() {
@Override
public void run() {
response=adapter.placeOrder(order);
latch.countDown();
}
});
verify(mockExchange,timeout(10) ).placeOrder(eq(order), callbackCaptor.capture());
//the timeout method is not really recommended and could also fail randomly if the thread takes more than 10ms
callbackCaptor.getValue().onSuccess();
latch.await(1000,TimeUnit.MILLISECONDS);
assertEquals(true,response);
}
}
对于这类测试,我喜欢使用一个称为awaitility的小库。 您可以使用倒计时闩锁自己进行操作,但是正如您所看到的那样,您必须使用弯刀来破坏您的测试以使其正常工作。
在此测试中,您应该在等待闩锁后致电验证。
代码中的另一个问题是private Boolean response
。 由于要在另一个线程中进行更改,因此应使AtomicBoolean
或至少声明为volatile
。
我不确定我是否正确理解你。 如果您想测试一个线程无限期地等待,直到另一线程做某事,那么我会说您做不到。 因为这意味着您要询问程序是否终止。 相反,您可以做两件事。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.