I have Quarkus app and I am trying to test my reactive Controller REST APIs using RestAssured.
And I am using smallrye-mutiny for developing my REST APIs.
The issue is when running the test RestAssured is trying to serialize the Uni and it throwing the following exception saying it could not found a serializer for Uni type. :
Caused by:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of
`io.smallrye.mutiny.Uni` (no Creators, like default constructor, exist): abstract types either
need to be mapped to concrete types, have custom deserializer, or contain additional type
information
at [Source: (String)
{
"header":{
"statusCode":"99-9999",
"statusDescription":"com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)"
}
}
; line: 1, column: 1]
Here is how my code looks like:
My Service Layer:
import io.smallrye.mutiny.Uni;
@ApplicationScoped
public class AccountOpeningServiceImpl implements AccountOpeningService {
@Override
public Uni<GetRandomNumberResponseApi> getRandomNumber(GetRandomNumberRequestApi requestApi) {
Uni<GetRandomNumberResponseApi> numberUni = Uni.createFrom().item(() -> GetRandomNumberResponseApi.builder().number(10).build()))
return numberUni;
}
My Controller :
import io.smallrye.mutiny.Uni;
@Path("")
public class AccountOpeningController {
@Inject
AccountOpeningService accountOpeningService;
@POST
@Path("/random-number")
public Uni<GetRandomNumberResponseApi> getRandomNumber(@Valid GetRandomNumberRequestApi requestApi) {
return accountOpeningService.getRandomNumber(requestApi);
}
And finally here is my test how it looks like.
@QuarkusTest
public class AccountOpeningControllerTest {
@InjectMock
AccountOpeningService accountOpeningService;
@Inject
MockUtil mockUtil;
@Test
void getRandomNumber() throws IOException {
GetRandomNumberRequestApi requestApi = mockUtil.getMock("Get_Random_Number_Request.json",
GetRandomNumberRequestApi.class);
GetRandomNumberResponseApi responseApi = mockUtil.getMock("Get_Random_Number_Response.json",
GetRandomNumberResponseApi.class);
when(accountOpeningService.getRandomNumber(requestApi)).thenReturn(Uni.createFrom().item(responseApi));
Uni<GetRandomNumberResponseApi> response = given()
.contentType(MediaType.APPLICATION_JSON)
.body(requestApi)
.when()
.post("/get-random-number")
.then()
.statusCode(200)
.extract()
.as(new TypeRef<Uni<GetRandomNumberResponseApi>>() {
});
GetRandomNumberResponseApi actualResponse = response.subscribe()
.withSubscriber(UniAssertSubscriber.create())
.assertCompleted()
.getItem();
Assertions.assertEquals(responseApi, actualResponse);
}
Any help, advices, resources?
That's because RestAssured tries to serialize a mock object. That mock object has extra properties like
mockitoInterceptorand so on. And one or more of those properties in the tree are not serializable by Jackson.So use real objects as request body and as expected response.
The following test will work