Ожидание внешнего события, прежде чем продолжить тестирование - PullRequest
0 голосов
/ 18 октября 2019

Контекст: я пишу модульный тест для службы 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, который бы лучше соответствовал моим потребностям?

...