2

I'm trying to test some reactive code implemented with mutiny on quarkus 2.2. This code do some sql query and I want a transactional method.

From my knowledge , for testing reactive code I have to await explicitly the result. But when there is transaction I got a io.quarkus.runtime.BlockingOperationNotAllowedException: Cannot start a JTA transaction from the IO thread.

here the test :

  void myTest() throws InterruptedException, SystemException, NotSupportedException {
    final Prestation prestation = Prestation.builder().build();
    final Uni<Uni<Integer>> uniUni = Uni.createFrom().voidItem().onItem().transformToUni(unused -> prestationCreate.upsert(prestation)).onItem()
            .transformToUni(aBoolean -> {
                return prestationClosedThePreviousDaySelect.select2Multi(LocalDate.of(2021, 04, 29))
                        .collect().asList();
            })
            .onItem()
            .transformToUni(prestations -> Uni.createFrom().item(prestationRepository.deleteAll()))
            .runSubscriptionOn(Infrastructure.getDefaultExecutor());

    final UniAssertSubscriber<Uni<Integer>> uniUniAssertSubscriber = uniUni.subscribe().withSubscriber(UniAssertSubscriber.create());
    uniUniAssertSubscriber.awaitItem()
            .assertCompleted();
}

With this code the exception will be thrown at the last line.

If I replace the last line with listUniAssertSubscriber.assertCompleted();, tests fails with "Expected a completion event, but didn't received it."

Anybody know if there is a way to test reactive code with transaction ?

Ben
  • 103
  • 1
  • 7
  • How are you starting your transaction?, I cannot see it on the example, which are your dependencies regarding database access and transaction?, are you using panache? – Javier Toja Sep 21 '21 at 13:54
  • Please correct me if my interpretation is wrong: prestationClosedThePreviousDaySelect.select2Multi is producing its result on an I/O thread (you can add .log() to check), and deleteAll is transactional? In that case, it's not a runSubscriptionOn that you need, but an emitOn(...) just before the onItem(). – Clement Sep 22 '21 at 07:51
  • 1
    Thank you @Clement, when a use emitOn instead runSubsritionOn there is no more exceptions – Ben Sep 28 '21 at 15:02

1 Answers1

0

(copying my comment, confirmed by the reporter)

prestationClosedThePreviousDaySelect.select2Multi produces its result on an I/O thread (you can add .log() to check), and deleteAll is transactional?. In that case, it's not a runSubscriptionOn that you need, but an emitOn(...) just before the onItem()

Clement
  • 2,817
  • 1
  • 12
  • 11