Reputation: 2554
I know that I can test a method that returns an Uni
:
@Test
public void testUni() {
service.doSomething().invoke(data -> {
// run assertions
}).subscribe().withSubscriber(UniAssertSubscriber.create()).assertCompleted();
}
But what if I want to test the method that subscribes to the Uni
itself? For example, consider this piece of code:
public void execute() {
service.reprocessAll().subscribe().with(
success -> log.info("Reprocessing ran successfully."),
error -> log.severe("Reprocessing failed: " + error.getMessage())
);
}
If I try to test it like this...
@Test
public void shouldLogSuccessAfterReprocessing() {
service.execute()
Mockito.verify(log, times(1)).success("Reprocessing ran successfully");
}
The test will fail due to a race condition. I mean, the test code will run before the actual code under test (the log.success
call). So how can I tell the test to wait for the Uni to complete? Or how could I refactor this to make it testable?
Upvotes: 1
Views: 394
Reputation: 16354
The proper question would be how to design the code so that it is unit-testable which may lead a different answer than the one I will be writing here to respond to your current need.
Since the service#reprocessAll
computation will be triggered on the background, and you have no means of controlling it behavior as your #service
method simply returns void
, you can block the calling unit runtime thread awaiting for the processing to finish:
@Test
public void shouldLogSuccessAfterReprocessing() throws Exception {
service.execute()
Thread.sleep(1000); // wait for reprocessAll to finish then proceed with assertions
Mockito.verify(log, times(1)).success("Reprocessing ran successfully");
}
For finer control, you can use the awaitiliy
library for condition testing.
Upvotes: 1