これは、なにをしたくて書いたもの?
2025年12月にREST Assuredが6.0.0になっていて、Eclipse Yasson 3をサポートするようになっていたので少し見ておこうかなと。
REST Assured 6.0とそれ以前
REST AssuredはREST APIをテストするためのライブラリーです。
Jakarta EEなどでのテストでは、よく見かけるライブラリーなのかなと思います。
REST Assured自体は便利なのですが、JSON-B 3.0を長らくサポートしていないという問題がありました。
Support JSON-B 3.0 (Jakarta EE 10) · Issue #1651 · rest-assured/rest-assured · GitHub
これがREST Assured 6.0になり解消されたというのが今回注目しているポイントです。
現在のREST Assuredは6.0と5.5の2系統がメンテナンスされているようですね。
それぞれのポイントはこちら。
- 6.0
- ReleaseNotes60 · rest-assured/rest-assured Wiki · GitHub
- Java 17以上が必要
- 内部的にGroovy 5.xを使用
- Spring Framework 7.xをサポート、最小バージョンは5.3
- Jackson 3をサポート
- Eclipse Yasson 3をサポート、かつ最小バージョン
- Apache Johnzon 2をサポート、かつ最小バージョン
- 5.5
- Java 8以上が必要
- 内部的にGroovy 4.xを使用
- Spring Framework 7.xをサポート(5.5.7以降)、最小バージョンは5.1
- Jacksonのサポートは2まで
- Eclipse Yasson 1をサポート
- Apache Johnzon 1をサポート
- Jakarta EE 10に対応
Jakarta EE 10に対応するにはREST Assured 6.0以降になるのかなと思ったのですが、どうやらそうではなさそうです。
どちらかというとJava 17以降を必要としていることが大きく、これで対応可能なライブラリーなどが変わった感じですね。
Eclipse Yassonなどが良い例です。
で、自分がJSON-B 3.0(Eclipse Yasson 3)への対応を気にしていたのは、Jakarta EEサーバーではJSONを扱う時に
JacksonではなくJSON-Bを使用していることが多く、JSON-B 3.0を使えなかったのはけっこう引っかかっていたからですね。
JSONのシリアライザーの優先順位は、Jacksonが最初のまま変わらないようですが。
- JSON using Jackson 3 (databind)
- JSON using Jackson 2 (Faster Jackson (databind))
- JSON using Jackson (databind)
- JSON using Gson
- JSON using Johnzon
- JSON-B using Eclipse Yasson
- XML using Jakarta EE
- XML using JAXB
Usage / Object Mapping / Serialization / Content-Type based Serialization
今回はWildFly 39を使って、REST Assured 6.0を簡単に試してみましょう。
環境
今回の環境はこちら。
$ java --version openjdk 25.0.2 2026-01-20 OpenJDK Runtime Environment (build 25.0.2+10-Ubuntu-124.04) OpenJDK 64-Bit Server VM (build 25.0.2+10-Ubuntu-124.04, mixed mode, sharing) $ mvn --version Apache Maven 3.9.14 (996c630dbc656c76214ce58821dcc58be960875b) Maven home: $HOME/.sdkman/candidates/maven/current Java version: 25.0.2, vendor: Ubuntu, runtime: /usr/lib/jvm/java-25-openjdk-amd64 Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "6.8.0-107-generic", arch: "amd64", family: "unix"
準備
まずはテスト対象のアプリケーションを作成しましょう。
Maven依存関係など。
<properties> <maven.compiler.release>25</maven.compiler.release> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.wildfly.bom</groupId> <artifactId>wildfly-ee-with-tools</artifactId> <version>39.0.1.Final</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.junit</groupId> <artifactId>junit-bom</artifactId> <version>5.11.3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- Maven War Pluginにweb.xmlを省略させるため --> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>jakarta.ws.rs</groupId> <artifactId>jakarta.ws.rs-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>jakarta.enterprise</groupId> <artifactId>jakarta.enterprise.cdi-api</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.arquillian.junit5</groupId> <artifactId>arquillian-junit5-container</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.wildfly.arquillian</groupId> <artifactId>wildfly-arquillian-container-remote</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.shrinkwrap.resolver</groupId> <artifactId>shrinkwrap-resolver-depchain</artifactId> <version>3.3.5</version> <scope>test</scope> <type>pom</type> </dependency> <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.27.7</version> <scope>test</scope> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <version>6.0.0</version> <scope>test</scope> </dependency> <!-- wildfly-ee BOMより--> <dependency> <groupId>org.eclipse</groupId> <artifactId>yasson</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <finalName>ROOT</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>3.5.5</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-maven-plugin</artifactId> <version>5.1.5.Final</version> <executions> <execution> <id>package</id> <goals> <goal>package</goal> </goals> </execution> <execution> <id>start-before-integration-test</id> <phase>pre-integration-test</phase> <goals> <goal>start</goal> </goals> </execution> <execution> <id>shutdown-after-integration-test</id> <phase>post-integration-test</phase> <goals> <goal>shutdown</goal> </goals> </execution> </executions> <configuration> <overwrite-provisioned-server>true</overwrite-provisioned-server> <discover-provisioning-info> <version>39.0.1.Final</version> </discover-provisioning-info> </configuration> </plugin> </plugins> </build>
依存ライブラリーのバージョンは基本的にWildFlyのBOMで解決します。テストコードではArquillianを使いますが、この時点では
JUnit 5を使うことになります(JUnit 6は次のWildFly Arquillian Adapterでの対応です)。
Arquillianの実行形態はRemoteです。
REST Assuredは単純に追加。
GettingStarted · rest-assured/rest-assured Wiki · GitHub
Eclipse YassonはこれもWildFlyのBOMで管理されているバージョンを指定します。現時点では3.0.4です。
WildFlyはWildFly Maven Pluginでプロビジョニングします。またインテグレーションテスト時に起動と停止もできるように
しておきます。
Maven Failsafe Pluginを入れておくことをお忘れなく。
Jakarta RESTful Web Servicesの有効化。
src/main/java/org/littlewings/restassured/RestApplication.java
package org.littlewings.restassured; import jakarta.ws.rs.ApplicationPath; import jakarta.ws.rs.core.Application; @ApplicationPath("/") public class RestApplication extends Application { }
リソースクラス。
src/main/java/org/littlewings/restassured/echo/EchoResource.java
package org.littlewings.restassured.echo; import jakarta.enterprise.context.ApplicationScoped; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.GET; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.core.MediaType; import java.util.Optional; @Path("/echo") @ApplicationScoped public class EchoResource { @GET @Produces(MediaType.APPLICATION_JSON) public EchoResponse get(@QueryParam("word") String word) { return new EchoResponse("★★★Hello %s!!★★★".formatted(Optional.ofNullable(word).orElse("World"))); } @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public EchoResponse post(EchoRequest echoRequest) { return new EchoResponse("★★★Hello %s!!★★★".formatted(Optional.ofNullable(echoRequest.word()).orElse("World"))); } }
リクエスト、レスポンスクラス。
src/main/java/org/littlewings/restassured/echo/EchoRequest.java
package org.littlewings.restassured.echo; public record EchoRequest( String word ) { }
src/main/java/org/littlewings/restassured/echo/EchoResponse.java
package org.littlewings.restassured.echo; public record EchoResponse( String message ) { }
動作確認しておきましょう。WildFlyを起動。
$ mvn wildfly:dev
確認。
$ curl localhost:8080/echo {"message":"★★★Hello World!!★★★"} $ curl localhost:8080/echo?word=REST+Assured {"message":"★★★Hello REST Assured!!★★★"} $ curl -X POST localhost:8080/echo --json '{}' {"message":"★★★Hello World!!★★★"} $ curl -X POST localhost:8080/echo --json '{"word": "REST Assured"}' {"message":"★★★Hello REST Assured!!★★★"}
OKですね。1度結果を削除。
$ mvn clean
REST Assuredを使ってテストコードを書く
では、REST Assuredを使ってテストコードを書きます。
src/test/java/org/littlewings/restassured/echo/EchoResourceIT.java
package org.littlewings.restassured.echo; import io.restassured.RestAssured; import io.restassured.config.ObjectMapperConfig; import io.restassured.config.RestAssuredConfig; import io.restassured.mapper.ObjectMapperType; import jakarta.ws.rs.ApplicationPath; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import java.io.File; import java.net.URL; import java.nio.file.Path; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit5.container.annotation.ArquillianTest; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.littlewings.restassured.RestApplication; import static io.restassured.RestAssured.given; import static io.restassured.RestAssured.when; import static org.assertj.core.api.Assertions.assertThat; @ArquillianTest @RunAsClient class EchoResourceIT { @ArquillianResource private URL deploymentUrl; private String resourcePrefix = RestApplication.class .getAnnotation(ApplicationPath.class) .value() .replaceFirst("^/", ""); @Deployment static WebArchive createDeployment() { /* // 依存ライブラリーが必要な場合は以下を追加 File[] compileAndRuntimeScopeDependencyFiles = Maven .resolver() .loadPomFromFile("pom.xml") .importCompileAndRuntimeDependencies() .resolve() .withTransitivity() .asFile(); */ File mainResources = Path.of("src/main/resources").toFile(); return ShrinkWrap .create(WebArchive.class) .addPackages(true, RestApplication.class.getPackage()) .addAsResource(mainResources, ""); // 依存ライブラリーが必要な場合は以下を追加 // .addAsLibraries(compileAndRuntimeScopeDependencyFiles); } @BeforeEach void setUp() { RestAssured.baseURI = deploymentUrl + resourcePrefix; // ObjectMapperをJSON-Bで固定 RestAssured.config = RestAssuredConfig.config().objectMapperConfig( ObjectMapperConfig.objectMapperConfig().defaultObjectMapperType(ObjectMapperType.JSONB) ); } @Test void echoGet() { EchoResponse response1 = when() .get("/echo") .then() .statusCode(Response.Status.OK.getStatusCode()) .contentType(MediaType.APPLICATION_JSON) .extract() .as(EchoResponse.class); assertThat(response1.message()).isEqualTo("★★★Hello World!!★★★"); EchoResponse response2 = given() .queryParam("word", "REST Assured") .when() .get("/echo") .then() .statusCode(Response.Status.OK.getStatusCode()) .contentType(MediaType.APPLICATION_JSON) .extract() .as(EchoResponse.class); assertThat(response2.message()).isEqualTo("★★★Hello REST Assured!!★★★"); } @Test void echoPost() { EchoResponse response1 = given() .contentType(MediaType.APPLICATION_JSON) .body("{}") .when() .post("/echo") .then() .contentType(MediaType.APPLICATION_JSON) .extract() .as(EchoResponse.class); assertThat(response1.message()).isEqualTo("★★★Hello World!!★★★"); EchoResponse response2 = given() .contentType(MediaType.APPLICATION_JSON) .body(new EchoRequest("REST Assured")) .when() .post("/echo") .then() .contentType(MediaType.APPLICATION_JSON) .extract() .as(EchoResponse.class); assertThat(response1.message()).isEqualTo("★★★Hello World!!★★★"); } }
雛形的にShrinkwrap Resolversを使って依存ライブラリーもデプロイするコードを書いていたのですが、今回はcompileおよび
runtimeスコープの依存ライブラリーがないのでそのままだと実行に失敗します。
@Deployment static WebArchive createDeployment() { /* // 依存ライブラリーが必要な場合は以下を追加 File[] compileAndRuntimeScopeDependencyFiles = Maven .resolver() .loadPomFromFile("pom.xml") .importCompileAndRuntimeDependencies() .resolve() .withTransitivity() .asFile(); */ File mainResources = Path.of("src/main/resources").toFile(); return ShrinkWrap .create(WebArchive.class) .addPackages(true, RestApplication.class.getPackage()) .addAsResource(mainResources, ""); // 依存ライブラリーが必要な場合は以下を追加 // .addAsLibraries(compileAndRuntimeScopeDependencyFiles); }
依存ライブラリーを含む場合は、コメントアウトしている箇所を外しましょう。
またJSONのシリアライザーの優先順位は以下に書いてあるとおりなのですが、
Usage / Object Mapping / Serialization / Content-Type based Serialization
Shrinkwrap ResolversにGsonが含まれているのでそちらが有効になってしまいます。今回はJSON-Bを使うように明示しました。
@BeforeEach void setUp() { RestAssured.baseURI = deploymentUrl + resourcePrefix; // ObjectMapperをJSON-Bで固定 RestAssured.config = RestAssuredConfig.config().objectMapperConfig( ObjectMapperConfig.objectMapperConfig().defaultObjectMapperType(ObjectMapperType.JSONB) ); }
あとはmvn verifyでWildFlyのプロビジョニング・起動後にテストが行われ、終了後にWildFlyが停止します。
$ mvn verify
スタックトレースを見たりして確認してみましたが、サーバー側もテスト側もJSONのシリアライズ、デシリアライズには
JSON-Bが使われています。
これでやっとサーバーとテストでリクエスト、レスポンスに関するコードの共有がまともにできるようになりました…。
オマケ
mvn verifyでWildFlyまわりの処理をしてもいいのですが、毎回行うと手間です。今回は以下のようにしました。
テストとWildFlyへのデプロイは省略して、プロビジョニングだけ行ってWildFlyを起動。バックグラウンド実行になります。
$ mvn clean package -DskipTests -Dwildfly.package.deployment.skip && mvn wildfly:start
WildFly Maven Pluginの処理やWildFlyへのデプロイはスキップしてテストだけ実行。
$ mvn verify -Dwildfly.skip -Dwildfly.package.skip
これで毎回WildFlyをプロビジョニングしたり、起動・停止する時間を省略できます。なお、-Dwildfly.skipだけでよいのではと
思うかもしれませんがこのやり方だと両方必要です。
バックグラウンドで起動したままのWildFlyを停止するにはこちら。
$ mvn wildfly:shutdown
おわりに
REST Assured 6.0をWildFly 39+Arquillianで試してみました。
以前からREST AssuredでJakarta EE 10以降のJSON-Bが使えないことが気になっていたのですが、6.0になってようやく
解決しました。
これでソースコードとテストコードで同じライブラリーを使えるので、各ライブラリーごとにシリアライズ、デシリアライズの
挙動差や設定を調整しなくてよくなりますね。