Контекст: я пишу модульный тест для службы gRPC. Я хочу убедиться, что метод макета на стороне сервера вызывается. Я использую легкий макет. Чтобы быть уверенным, что мы получили ответ от gRPC (что бы это ни было), мне нужно приостановить поток перед тем, как легко проверять вызовы.
Итак, я попробовал что-то подобное, используя LockSupport:
@Test
public void alphaMethodTest() throws Exception
{
Dummy dummy = createNiceMock(Dummy.class);
dummy.alphaMethod(anyBoolean());
expectLastCall().once();
EasyMock.replay(dummy);
DummyServiceGrpcImpl dummyServiceGrpc = new DummyServiceGrpcImpl();
bcreuServiceGrpc.setDummy(dummy);
DummyServiceGrpc.DummyServiceStub stub = setupDummyServiceStub();
Thread thread = Thread.currentThread();
stub.alphaMethod(emptyRequest, new StreamObserver<X>(){
@Override
public void onNext(X value) {
LockSupport.unpark(thread);
}
}
Instant expirationTime = Instant.now().plus(pDuration);
LockSupport.parkUntil(expirationTime.toEpochMilli());
verify(dummy);
}
Но у меня есть много подобных тестов (около 40), и я подозреваю, что есть проблема с многопоточностью. Я обычно получаю один или два, не пройдя шаг проверки, иногда все они проходят. Я пытаюсь использовать ReentrantLock с условием вместо этого. Но опять-таки некоторые сбои (IllegalMonitorStateException для signalAll):
@Test
public void alphaMethodTest() throws Exception
{
Dummy dummy = createNiceMock(Dummy.class);
dummy.alphaMethod(anyBoolean());
expectLastCall().once();
EasyMock.replay(dummy);
DummyServiceGrpcImpl dummyServiceGrpc = new DummyServiceGrpcImpl();
bcreuServiceGrpc.setDummy(dummy);
DummyServiceGrpc.DummyServiceStub stub = setupDummyServiceStub();
ReentrantLock lock = new ReentrantLock();
Condition conditionPromiseTerminated = lock.newCondition();
stub.alphaMethod(emptyRequest, new StreamObserver<X>(){
@Override
public void onNext(X value) {
conditionPromiseTerminated.signalAll();
}
}
Instant expirationTime = Instant.now().plus(pDuration);
conditionPromiseTerminated.awaitUntil(new Date(expirationTime.toEpochMilli()));
verify(dummy);
}
Я сожалею, что не могу предоставить вам работающий пример, мой текущий код использует частный API: /.
Как вы думаете, LockSupport может вызвать проблемы из-за запуска нескольких тестов? Я что-то упускаю, используя поддержку блокировки или повторную блокировку? Думаете ли вы о каком-либо другом классе параллельного API, который бы лучше соответствовал моим потребностям?