JerseyでREST APIを作成した時、JerseyTestがJUnit5で動かなくて困ったことがありました。
どうやら、JerseyTestはJUnit5との互換性がないようです。(2021/07/05時点)
でも、JerseyTestをJUnit5で実行したいんだよなぁ
ということで、この記事ではJerseyTestをJUnit5で実行する方法を紹介します。
今回は例として、こんな感じのサンプルプログラムを作成しました。
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.core.Response;
@Path("example")
public class ExampleResource {
@GET
@Path("healthcheck")
public Response helthCheck() {
return Response.ok().build();
}
}
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import jakarta.ws.rs.core.Application;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class ExapmleResourceTest extends JerseyTest {
@BeforeAll
public void before() throws Exception {
super.setUp();
}
@AfterAll
public void after() throws Exception {
super.tearDown();
}
@Override
protected Application configure() {
return new ResourceConfig(ExampleResource.class);
}
@Test
public void test() {
Response response = target("example/healthcheck").request().get();
assertEquals(Status.OK.getStatusCode(), response.getStatus());
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>simple-service</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>simple-service</name>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey</groupId>
<artifactId>jersey-bom</artifactId>
<version>${jersey.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<inherited>true</inherited>
<configuration>
<source>15</source>
<target>15</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.example.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<jersey.version>3.0.2</jersey.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.jupiter.version>5.7.1</junit.jupiter.version>
</properties>
</project>
JerseyのTestをJUnit5で実行する手順
1. pom.xmlを書き換える
JUnit5とJUnit4では、pom.xmlの<dependencies>に記載する内容が異なります。
JUnit4で実行するとき
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
JUnit5で実行するとき
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.7.1</version>
<scope>test</scope>
</dependency>
JUnit5を動かすには、最低限junit-jupiter-apiとjunit-jupiter-engineがあればOKです。
また、Jersey Test Frameworkも<dependencies>に加えておきましょう。
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
</dependency>
2. importを書き換える
JUnit5では、新しいorg.junit.jupiterパッケージを使用します。importを書き換えましょう。
JUnit4
import org.junit.Test;
JUnit5
import org.junit.jupiter.api.Test;
3. 古いアノテーションとクラス名を書き換える
ポイントを抜き出して説明します。
@TestInstance(TestInstance.Lifecycle.PER_CLASS)、@Brefore→@BeforeAll、@After→@AfterAll
アノテーションを追加します。
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)で、クラス単位でインスタンスを生成するように変更しています。この設定を加えることで、@BeforeAllと@AfterAllが使用できるようになります。
@Brefore → @BeforeAll
@After → @AfterAll
それに伴い、importも下記のものに更新します。
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.TestInstance;
Assertionsを使用
JUnit5では、org.junit.jupiter.api.Assertionsクラスのstaticメソッドとしてアサーションを使用します。こちらも書き換えておきましょう。
例では、このようにimportしています。
import static org.junit.jupiter.api.Assertions.assertEquals;
4. setUp()とtearDown()を呼び出すようにする
最後に一つ、注意点があります。
JUnit5でJerseyTestを実行するには、setUp()とtearDown()は明示的に呼び出す必要があります。
@BeforeAll
public void before() throws Exception {
super.setUp();
}
@AfterAll
public void after() throws Exception {
super.tearDown();
}
JUnit4では特にコーディングしなくても呼び出されていたのですが、JUnit5からは呼び出されないようになったみたいです。
setUp()とtearDown()を呼び出さないとNullPointerExceptionになります。
java.lang.NullPointerException: Cannot invoke "org.glassfish.jersey.test.spi.TestContainer.getBaseUri()" because the return value of "org.glassfish.jersey.test.JerseyTest.getTestContainer()" is null
setUp()とtearDown()は明示的に呼び出すように実装しましょう。
おわり
これで、JerseyTestがJUnit5で実行されるようになりました。
もしかしたら、今後のバージョンでsetUp()とtearDown()を呼び出さなくてもJUnit5で実行できるようになるかも。
期待しておきましょう。
コメント