MicroShed / microshed-testing

A test framework for black-box testing MicroProfile and Jakarta EE applications
https://microshed.org/microshed-testing/
Apache License 2.0
65 stars 23 forks source link

Access the response status and headers of the Client Response #130

Closed rieckpil closed 4 years ago

rieckpil commented 4 years ago

Is your feature request related to a problem? Please describe.

Right now we can only write assertions based on the response type of the JAX-RS method class. It would be nice if we can access the actual JAX-RS Response to inspect HTTP headers & the response status.

Describe the solution you'd like

Maybe reconsider the solution with the injection of the JAX-RS resources class to a static field using @RESTClient PersonResource personResource (which is also not that intuitive IMHO). It would be nice to just inject a prepared JAX-RS Client which is already bound to the application context, has some default provider (e.g. JSON/XML) and can be further configured if required. The Spring framework, for example, provides a WebTestClient during a test execution with the described setup.

I wouldn't go that far as the Spring Framework and also add assertion methods on the client class and just prepare it to be used by the developer like in his production code.

The downside of this idea: The user has to enter the actual path for the JAX-RS resource he/she wants to access, which is currently not required. This might also be a small plus, as with the current solution your integration test would never recognize a URL change in the API e.g. /resources/persons to /api/persons.

Describe alternatives you've considered

Additional context

none

aguibert commented 4 years ago

I like the idea of giving users more low-level validation access to their HTTP endpoints. Currently users can do this if the REST client returns a javax.ws.rs.core.Response object, but in many cases REST clients do not because it's more convenient to simply return a POJO from the JAX-RS method.

One popular REST testing library I know if is REST-assured. Here is a good article about it: https://www.baeldung.com/rest-assured-tutorial If you look at section (7) it talks about configuring the library, perhaps we could automatically detect the presence of the RestAssured class and if it's present then microshed would automatically bootstrap it (e.g. set baseURI, base path, port, etc). This would allow us to have a test case that looks like this:

@MicroShedTest
public class MyTest {
  @Container
  public static ApplicationContainer app = // usual config

  @Test
  public void testCreatePerson() {
    // validate that POST request to
    // http://<container-ip>:<container-port>/myservice/?name=Hank?age=52
    // returns HTTP 200 with content type JSON
    given()
        .contentType(JSON)
        .queryParam("name", "Hank")
        .queryParam("age", 52)
      .when()
        .post("/")
      .then()
        .statusCode(200)
        .contentType(JSON);
  }
}
rieckpil commented 4 years ago

This looks quite good 👍

aguibert commented 4 years ago

created a draft PR for the integration here: https://github.com/MicroShed/microshed-testing/pull/134

It can't be merged until the corresponding PR I made on REST-assured gets merged though

rieckpil commented 4 years ago

wow, that was fast :+1: I'll try it over the weekend while building REST-Assured with your PR locally

rieckpil commented 4 years ago

works great and I really like the given/when/then structure of Rest Assured.

Just out of curiosity, if now a user wants to plug a custom MessageBodyReader or MessageBodyWriter e.g JAXB or for whatever reason, he/she uses binary formats like Kryo, this would always result in effort and adjustment within RestAssured, or? I assume 80% of the use cases are fine with JSON but the rest might need something different

aguibert commented 4 years ago

RestAssured has builtin converters for JSON and XML formats, but if a user wants to implement a converter to handle a custom data format.

For JSON-B integration with RestAssured I could have just written the converter in MicroShed code, but then we'd need to have a dependency on RestAssured which I wanted to avoid (i.e. not even an optional dependency)

aguibert commented 4 years ago

PR #134 adds the integration with REST Assured and is now merged, it will be available in the next release (probably 0.6.3)