diff --git a/README.md b/README.md index d5cdd24e..942783ab 100644 --- a/README.md +++ b/README.md @@ -17,57 +17,6 @@ MicroShed Testing aims to: 1. work with any Java EE, Jakarta EE or MicroProfile runtime 1. provide true-to-production tests -# How to use in an existing project: - -Add `microshed-testing-testcontainers` and `junit-jupiter` as test-scoped dependencies: -```xml - - - org.microshed - microshed-testing-testcontainers - 0.9.2 - test - - - - org.junit.jupiter - junit-jupiter - 5.10.1 - test - - - - -``` - -## How to test a Java EE application - -Add `microshed-testing-core` as a test-scoped dependency: -```xml - - - org.microshed - microshed-testing-core - 0.9.2 - test - - -``` - -## How to test a Jakarta EE application - -Add `microshed-testing-core-jakarta` as a test-scoped dependency: -```xml - - - org.microshed - microshed-testing-core-jakarta - 0.9.2 - test - - -``` - # How to try out a sample locally: ### Run with Maven: @@ -90,95 +39,79 @@ NOTE: If a container is consistantly timing out on your system you can set a lon NOTE: If a mockserver has started, but HTTP calls are consistantly timing out on your system you can set a longer timeout (in milliseconds) with the system property `mockserver.maxSocketTimeout` default value is 120000 milliseconds. -### Tested with: +# Supported application-servers: - OpenLiberty - Wildfly -- Payara Micro -- Apache TomEE +- Payara Micro / Full - Quarkus -To change which app server is used, [un]comment sections of the test app's Dockerfile at `sample-apps/jaxrs-json/Dockerfile` +# Supported runtimes: +`microshed-testing-core` supports the Javax namespace up to and including version 0.9.2. Starting from version 0.9.3, the Jakarta namespace is supported. -# What it looks like +# Quick Start -Assume we have a basic JAX-RS application that can perform create, update, and delete -operations on 'Person' data objects. It may look something like this: +To get started writing a test with MicroShed Testing, add `system-test` and `junit-jupiter` as test-scoped dependencies: -```java -@Path("/people") -@ApplicationScoped -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -public class PersonService { - - private final PersonRepo personRepo = // ... - - @GET - public Collection getAllPeople() { - return personRepo.values(); - } - - @GET - @Path("/{personId}") - public Person getPerson(@PathParam("personId") long id) { - Person foundPerson = personRepo.get(id); - if (foundPerson == null) - throw new NotFoundException("Person with id " + id + " not found."); - return foundPerson; - } - - // ... -} +```xml + + org.microshed + microshed-testing-testcontainers + 0.9.2 + test + + + + + org.junit.jupiter + junit-jupiter + 5.10.1 + test + ``` -Using MicroShed Testing, we can write an integration test that looks something like this: +Once you have the above dependencies added, create a new test class with the following items: +1. Annotate the class with `@MicroShedTest` +1. Create a `public static ApplicationContainer` field +1. Inject one or more `public static` JAX-RS resource classes ```java -import static org.junit.jupiter.api.Assertions.*; -import javax.ws.rs.NotFoundException; -import org.junit.jupiter.api.Test; import org.microshed.testing.jaxrs.RESTClient; import org.microshed.testing.jupiter.MicroShedTest; import org.microshed.testing.testcontainers.ApplicationContainer; import org.testcontainers.junit.jupiter.Container; @MicroShedTest -public class BasicJAXRSServiceTest { +public class MyTest { - // This will search for a Dockerfile in the repository and start up the application - // in a Docker container, and wait for it to be ready before starting the tests. @Container public static ApplicationContainer app = new ApplicationContainer() .withAppContextRoot("/myservice"); - - // This injects a REST _Client_ proxy of the PersonService shown above - // This allows us to easily invoke HTTP requests on the running application container + @RESTClient - public static PersonService personSvc; - - @Test - public void testGetPerson() { - // This invokes an HTTP POST request to the running container, which triggers - // the PersonService#createPerson endpoint and returns the generated ID - Long bobId = personSvc.createPerson("Bob", 24); - - // Using the generated ID, invoke an HTTP GET request to read the record we just created - // The JSON response will be automatically converted to a 'Person' object using JSON-B - Person bob = personSvc.getPerson(bobId); - - assertEquals("Bob", bob.name); - assertEquals(24, bob.age); - assertNotNull(bob.id); - } + public static MyService mySvc; - @Test - public void testGetUnknownPerson() { - // This invokes an HTTP GET request to get a person with ID -1, which does not exist - // asserts that the application container returns an HTTP 404 (not found) exception - assertThrows(NotFoundException.class, () -> personSvc.getPerson(-1L)); - } - - // ... + // write @Test methods as normal } ``` +If the repository containing the tests does not have a `Dockerfile` in it, there are a few other options: + +* If the application's container image is produced by a different repository, a String docker image label can be + supplied instead: + +```java + @Container + public static ApplicationContainer app = new ApplicationContainer("myservice:latest") + .withAppContextRoot("/myservice"); +``` +* If a Dockerfile or container image label is not available, it is possible to use vendor-specific adapters that will + provide the default logic for building an application container. For example, the `microshed-testing-liberty` adapter will + automatically produce a testable container image roughly equivalent to the following Dockerfile: + +``` +FROM openliberty/open-liberty:full-java17-openj9-ubi +COPY src/main/liberty/config /config/ +ADD target/$APP_FILE /config/dropins +``` + +For a more complete introduction, see the [Walkthrough page](https://microshed.org/microshed-testing/features/Walkthrough.html) \ No newline at end of file diff --git a/core/src/main/java/org/microshed/testing/jaxrs/RestClientBuilder.java b/core/src/main/java/org/microshed/testing/jaxrs/RestClientBuilder.java index e84b309b..653ccaac 100644 --- a/core/src/main/java/org/microshed/testing/jaxrs/RestClientBuilder.java +++ b/core/src/main/java/org/microshed/testing/jaxrs/RestClientBuilder.java @@ -161,7 +161,7 @@ private static String locateApplicationPath(Class clazz) { if (AnnotationSupport.isAnnotated(clazz, ApplicationPath.class)) return AnnotationSupport.findAnnotation(clazz, ApplicationPath.class).get().value(); - // First check for a javax.ws.rs.core.Application in the same package as the resource + // First check for a jakarta.ws.rs.core.Application in the same package as the resource List> appClasses = ReflectionSupport.findAllClassesInPackage(resourcePackage, c -> Application.class.isAssignableFrom(c) && AnnotationSupport.isAnnotated(c, ApplicationPath.class), @@ -183,7 +183,7 @@ private static String locateApplicationPath(Class clazz) { } if (appClasses.size() == 0) { - LOG.info("No classes implementing 'javax.ws.rs.core.Application' found on classpath to set base path from " + clazz + + LOG.info("No classes implementing 'jakarta.ws.rs.core.Application' found on classpath to set base path from " + clazz + ". Defaulting base path to '/'"); return ""; } @@ -194,7 +194,7 @@ private static String locateApplicationPath(Class clazz) { .get(); ApplicationPath appPath = AnnotationSupport.findAnnotation(selectedClass, ApplicationPath.class).get(); if (appClasses.size() > 1) { - LOG.warn("Found multiple classes implementing 'javax.ws.rs.core.Application' on classpath: " + appClasses + + LOG.warn("Found multiple classes implementing 'jakarta.ws.rs.core.Application' on classpath: " + appClasses + ". Setting base path from the first class discovered (" + selectedClass.getCanonicalName() + ") with path: " + appPath.value()); } diff --git a/docs/features/Walkthrough.md b/docs/features/Walkthrough.md index 0e246f68..12f523e7 100644 --- a/docs/features/Walkthrough.md +++ b/docs/features/Walkthrough.md @@ -43,7 +43,7 @@ public class PersonService { Now assume we also have simple Dockerfile in our repository that packages up our application into a container which gets used in production. ``` -FROM open-liberty:full-java11-openj9 +FROM openliberty/open-liberty:full-java17-openj9-ubi COPY src/main/liberty/config /config/ ADD target/myservice.war /config/dropins ``` @@ -55,6 +55,7 @@ It doesn't really matter what's in the Dockerfile. What matters is we can start ## Add dependencies Given the above application code, we can start by adding maven dependencies: +`microshed-testing-core` supports the Javax namespace up to and including version 0.9.2. Starting from version 0.9.3, the Jakarta namespace is supported. ```xml @@ -65,13 +66,6 @@ Given the above application code, we can start by adding maven dependencies: test - - org.microshed - microshed-testing-core-jakarta - 0.9.2 - test - - org.junit.jupiter @@ -98,7 +92,7 @@ If you have never used JUnit Jupiter (JUnit 5) before with integration tests, th org.apache.maven.plugins maven-failsafe-plugin - 2.22.0 + 3.2.3 @@ -133,7 +127,7 @@ public class MyServiceIT { Before we can run the test, we need to define the application container. First we need to know what context root our application is available under. You may know this already, otherwise you can check the logs of your application runtime. They may look like this: ``` -Launching defaultServer (Open Liberty 19.0.0.8/wlp-1.0.31.cl190820190813-1136) on IBM J9 VM, version 8.0.5.40 - pxa6480sr5fp40-20190807_01(SR5 FP40) (en_US) +[ApplicationContainer] Launching defaultServer (Open Liberty 23.0.0.10/wlp-1.0.82.cl231020231002-1201) on Eclipse OpenJ9 VM, version 17.0.8.1+1 (en_US) [AUDIT ] CWWKE0001I: The server defaultServer has been launched. [AUDIT ] CWWKT0016I: Web application available (default_host): http://localhost:9080/myservice/ [AUDIT ] CWWKZ0001I: Application myservice started in 1.678 seconds. diff --git a/docs/index.md b/docs/index.md index 3519f7d8..1bb4ce69 100644 --- a/docs/index.md +++ b/docs/index.md @@ -53,7 +53,7 @@ Using MicroShed Testing, we can write an integration test that looks something l ```java import static org.junit.jupiter.api.Assertions.*; -import javax.ws.rs.NotFoundException; +import jakarta.ws.rs.NotFoundException; import org.junit.jupiter.api.Test; import org.microshed.testing.jaxrs.RESTClient; import org.microshed.testing.jupiter.MicroShedTest; @@ -115,7 +115,7 @@ provide the default logic for building an application container. For example, th automatically produce a testable container image roughly equivalent to the following Dockerfile: ``` -FROM open-liberty:full-java11-openj9 +FROM openliberty/open-liberty:full-java17-openj9-ubi COPY src/main/liberty/config /config/ ADD target/$APP_FILE /config/dropins ``` @@ -123,6 +123,7 @@ ADD target/$APP_FILE /config/dropins ## Quick Start To get started writing a test with MicroShed Testing, add `system-test` and `junit-jupiter` as test-scoped dependencies: +`microshed-testing-core` supports the Javax namespace up to and including version 0.9.2. Starting from version 0.9.3, the Jakarta namespace is supported. ```xml @@ -132,13 +133,6 @@ To get started writing a test with MicroShed Testing, add `system-test` and `jun test - - org.microshed - microshed-testing-core-jakarta - 0.9.2 - test - - org.junit.jupiter