简体   繁体   中英

Mock a JSON request parameter using Quarkus and RestAssured

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... )

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.

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM