Reputation: 3182
Using Quarkus, I have the following API.
@RequestScoped
@Path("/api/v1")
public class MyApi {
@POST
@Consumes(APPLICATION_JSON)
public Response create(Entity entityToCreate) {
if (entityToCreate.isValid()) {
// create the entity in my app...
return Response.ok().build();
} else {
return Response.status(BAD_REQUEST).build();
}
}
}
My Entity
class looks like this
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Entity {
private final String property1;
private final String property2;
// ...
@JsonCreator
public Entity(@JsonProperty("property1") String property1,
@JsonProperty("property2") String property2,
// ...
){
this.property1 = property1;
this.property2 = property2;
// ...
}
// getters for every property...
public boolean isValid() {
// check if the entity is valid, then return true or false
}
}
What I want to achieve, in my unit tests, is the following:
import static io.restassured.RestAssured.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@QuarkusTest
public class MyApiTest {
private final Entity entityMock = mock(Entity.class);
@Test
public void shouldCreateEntityWhenValid(){
when(entityMock.isValid()).thenReturn(true);
given()
.contentType(ContentType.JSON)
.body(entityMock)
.when()
.post("/api/v1")
.then()
.statusCode(200);
}
@Test
public void shouldNotCreateEntityWhenInvalid(){
when(entityMock.isValid()).thenReturn(false);
given()
.contentType(ContentType.JSON)
.body(entityMock)
.when()
.post("/api/v1")
.then()
.statusCode(400);
}
}
Currently, I'm stuck with the following error, because Jackson tries to deserialize the mock.
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.mockito.internal.invocation.mockref.MockWeakReference and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: blah blah blah... )
Upvotes: 0
Views: 5614
Reputation: 3182
I ended up mixing several test techniques, to validate both the JSON mapping and the method behaviour.
import static io.restassured.RestAssured.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@QuarkusTest
public class MyApiTest {
private final Entity entityMock = mock(Entity.class);
private final Entity validEntity = // [...] instantiate a valid entity here
private MyApi api;
@BeforeEach
void beforeEach() {
myApi = new MyApi();
}
// this test validates both the JSON parsing and the valid entity case
@Test
public void shouldCreateEntityWhenValid(){
given()
.contentType(ContentType.JSON)
.body(validEntity)
.when()
.post("/api/v1")
.then()
.statusCode(200);
}
// this test validates the invalid entity case
@Test
public void shouldNotCreateEntityWhenInvalid(){
when(entityMock.isValid()).thenReturn(false);
Response response = myApi.create(entityMock);
assertThat(response.getStatus()).isEqualTo(400);
}
}
Upvotes: 1
Reputation: 1131
Just create a real instance of your entity and let the validation happen.
Rest Assured is going to post an actual HTTP request in the test, so it serializes your mock as JSON. When the implementation handles the HTTP request, the request body is then deserialized into an entity. This entity is instantiated internally, so it’s not the same instance as created in the test.
Upvotes: 4