Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration with REST-assured #134

Merged
merged 1 commit into from
Jan 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019 IBM Corporation and others
* Copyright (c) 2019,2020 IBM Corporation and others
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
Expand All @@ -21,6 +21,7 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
Expand All @@ -44,15 +45,16 @@
*/
class MicroShedTestExtension implements BeforeAllCallback {

static final Logger LOGGER = LoggerFactory.getLogger(MicroShedTestExtension.class);
static final Logger LOG = LoggerFactory.getLogger(MicroShedTestExtension.class);

@Override
public void beforeAll(ExtensionContext context) throws Exception {
Class<?> testClass = context.getRequiredTestClass();
ApplicationEnvironment config = ApplicationEnvironment.load();
LOGGER.info("Using ApplicationEnvironment class: " + config.getClass().getCanonicalName());
LOG.info("Using ApplicationEnvironment class: " + config.getClass().getCanonicalName());
config.applyConfiguration(testClass);
config.start();
configureRestAssured(config);
injectRestClients(testClass);
}

Expand All @@ -79,7 +81,7 @@ private static void injectRestClients(Class<?> clazz) {
Object restClient = rcBuilder.build(restClientField.getType());
try {
restClientField.set(null, restClient);
LOGGER.debug("Injected rest client for " + restClientField);
LOG.debug("Injected rest client for " + restClientField);
} catch (Exception e) {
throw new ExtensionConfigurationException("Unable to set field " + restClientField, e);
}
Expand All @@ -99,14 +101,60 @@ private static String createJwtIfNeeded(Field restClientField) {
return null;
}

@SuppressWarnings({ "unchecked", "rawtypes" })
private static void configureRestAssured(ApplicationEnvironment config) {
Class<?> RestAssured = tryLoad("io.restassured.RestAssured");
if (RestAssured == null)
return;

try {
URL appURL = new URL(config.getApplicationURL());
String baseURI = appURL.getProtocol() + "://" + appURL.getHost();
int port = appURL.getPort();
String basePath = appURL.getPath();
LOG.info("Configuring RestAssured with baseURI=" + baseURI + " port=" + port + " basePath=" + basePath);

RestAssured.getField("baseURI").set(null, baseURI);
RestAssured.getField("basePath").set(null, basePath);
RestAssured.getField("port").set(null, port);
} catch (Exception e) {
LOG.warn("Unable to configure REST Assured because of: " + e.getMessage(), e);
}

try {
// Configure JSONB as the JSON object mapper by invoking:
// ObjectMapperType JSONB = ObjectMapperType.JSONB;
// ObjectMapperConfig omConfig = ObjectMapperConfig.objectMapperConfig().defaultObjectMapperType(JSONB);
// RestAssured.config = RestAssured.config.objectMapperConfig(omConfig);
ClassLoader cl = MicroShedTestExtension.class.getClassLoader();
Class<Enum> ObjectMapperType = (Class<Enum>) Class.forName("io.restassured.mapper.ObjectMapperType", false, cl);
Object JSONB = Enum.valueOf(ObjectMapperType, "JSONB");
Class<?> ObjectMapperConfig = Class.forName("io.restassured.config.ObjectMapperConfig", false, cl);
Object omConfig = ObjectMapperConfig.getMethod("objectMapperConfig").invoke(null);
omConfig = omConfig.getClass().getMethod("defaultObjectMapperType", ObjectMapperType).invoke(omConfig, JSONB);
Class<?> RestAssuredConfig = Class.forName("io.restassured.config.RestAssuredConfig", false, cl);
Object raConfig = RestAssured.getField("config").get(null);
raConfig = RestAssuredConfig.getMethod("objectMapperConfig", ObjectMapperConfig).invoke(raConfig, omConfig);
RestAssured.getField("config").set(null, raConfig);
LOG.debug("Regsitered JSONB ObjectMapper for REST Assured");
} catch (IllegalArgumentException e) {
// Prior to RestAssured 4.2.0 the ObjectMapperType.JSONB enum is not available
LOG.debug("Unable to configure JSON-B object mapper for REST Assured", e);
} catch (Exception e) {
LOG.warn("Unable to configure JSON-B object mapper for REST Assured", e);
}
}

@SuppressWarnings("unchecked")
private static Optional<Class<? extends Annotation>> getMpRestClient() {
return Optional.ofNullable((Class<? extends Annotation>) tryLoad("org.eclipse.microprofile.rest.client.inject.RestClient"));
}

private static Class<?> tryLoad(String clazz) {
try {
return Optional.of((Class<? extends Annotation>) Class.forName("org.eclipse.microprofile.rest.client.inject.RestClient",
false,
MicroShedTestExtension.class.getClassLoader()));
return Class.forName(clazz, false, MicroShedTestExtension.class.getClassLoader());
} catch (ClassNotFoundException | LinkageError e) {
return Optional.empty();
return null;
}
}
}
106 changes: 106 additions & 0 deletions docs/features/14_RestAssured.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
layout: post
title: "REST Assured"
---

MicroShed Testing provides auto-configuration for when [REST Assured](https://github.com/rest-assured/rest-assured) is available on the test classpath. REST Assured is a Java DSL library for easy testing of REST services. It is more verbose than using a REST client, but offers more direct control over the request and response.f

## Enable REST Assured

To enable REST Assured, add the following dependency to your pom.xml:

```xml
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
```

Any version of REST Assured will have basic integration with MicroShed Testing -- the application URL and port will be auto-configured.

As of REST Assured 4.2.0 or newer, a JSON-B based JSON ObjectMapper will be auto-configured.

Because of the auto-configuration, no specific configuration is required in your test classes.

## Example usage

Validating a simple `GET` request:

```java
import static io.restassured.RestAssured.given;
import static io.restassured.http.ContentType.JSON;
// ...

@MicroShedTest
public class RestAssuredTest {

@Container
public static ApplicationContainer app = new ApplicationContainer()
.withAppContextRoot("/myservice");

@Test
public void testCreatePerson() {
given()
.queryParam("name", "Hank")
.queryParam("age", 45)
.contentType(JSON)
.when()
.post("/")
.then()
.statusCode(200)
.contentType(JSON);
}
}
```

It is also possible to send/receive POJOs with the JSON-B based ObjectMapper:

```java
@Test
public void testGetPerson() {
// First create the Person
long bobId = given()
.queryParam("name", "Bob")
.queryParam("age", 24)
.contentType(JSON)
.when()
.post("/")
.then()
.statusCode(200)
.contentType(JSON)
.extract()
.as(long.class);

// Validate new created Person can be retrieved
Person bob = given()
.pathParam("personId", bobId)
.when()
.get("/{personId}")
.then()
.statusCode(200)
.contentType(JSON)
.extract()
.as(Person.class);
assertEquals("Bob", bob.name);
assertEquals(24, bob.age);
assertNotNull(bob.id);
}
```

For a complete working example, see the [RestAssuredTest class](https://github.com/MicroShed/microshed-testing/blob/master/sample-apps/everything-app/src/test/java/org/example/app/RestAssuredTest.java)

## Auto-configuration override

If you would like to use a different JSON ObjectMapper besides the default (JSON-B/Yasson), you can run the following code in your test initialization flow:

```java
import io.restassured.RestAssured;
import io.restassured.config.ObjectMapperConfig;
import io.restassured.mapper.ObjectMapperType;
// ...

ObjectMapperConfig omConfig = ObjectMapperConfig.objectMapperConfig().defaultObjectMapperType(ObjectMapperType.JACKSON_2);
RestAssured.config = RestAssured.config.objectMapperConfig(omConfig);
```
1 change: 1 addition & 0 deletions docs/features/98_Examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Sometimes code is worth a thousand words. Here are some pointers to working exam

- [Basic JAX-RS application using Gradle](https://github.com/MicroShed/microshed-testing/tree/master/sample-apps/jaxrs-json)
- [Basic JAX-RS application using Maven](https://github.com/MicroShed/microshed-testing/tree/master/sample-apps/maven-app)
- [Basic JAX-RS application using REST Assured](https://github.com/MicroShed/microshed-testing/blob/master/sample-apps/everything-app/src/test/java/org/example/app/RestAssuredTest.java)
- [JAX-RS and JDBC applicaiton using a PostgreSQL database](https://github.com/MicroShed/microshed-testing/tree/master/sample-apps/jdbc-app)
- [JAX-RS application secured with MP JWT](https://github.com/MicroShed/microshed-testing/tree/master/sample-apps/jaxrs-mpjwt)
- [JAX-RS and MongoDB application that depends on an external REST service](https://github.com/MicroShed/microshed-testing/tree/master/sample-apps/everything-app)
Expand Down
1 change: 1 addition & 0 deletions sample-apps/everything-app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dependencies {
testCompile group: 'org.slf4j', name: 'slf4j-log4j12', version: '1.7.29'
testCompile 'org.testcontainers:mockserver:1.12.3'
testCompile 'org.mock-server:mockserver-client-java:5.5.4'
testCompile 'io.rest-assured:rest-assured:4.2.0'
testImplementation 'org.junit.jupiter:junit-jupiter:5.5.2'
}

Expand Down
Loading