JerseyTest is not compatible with JUnit 5
When using JerseyTest with JUnit 5 a null pointer exception gets thrown:
java.lang.NullPointerException
at org.glassfish.jersey.test.JerseyTest.target(JerseyTest.java:564)
at org.glassfish.jersey.test.JerseyTest.target(JerseyTest.java:578)
The issue seems to be that the setup() and tearDown() functions in the JerseyTest class are not called in JUnit 5 as they would be in JUnit 4. JUnit 5 uses the convention of @Before and @After annotations.
Here is my workaround, in the test class that extends JerseyTest add the following two methods:
// do not name this setup()
@BeforeAll
public void before() throws Exception {
super.setUp();
}
// do not name this tearDown()
@AfterAll
public void after() throws Exception {
super.tearDown();
}
Hey, I created a JUnit 5 extension for using the JerseyTest framework if you'd like to check it out: https://github.com/hanleyt/jersey-junit
Let me know if you guys would be interested in integrating this development.
Thanks, Tomás
There is no need to worry. JUnit 5 ensures "Vintage" compatibility.
You juste have to import the JUnit 5 Vintage package:
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
Then, in your Jersey Test framework, just use JUnit 4 helpers:
package com.example.api.http;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
// JUnit 4 Test helper
import org.junit.Test;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Response;
// JUnit 5 Assertions (!!!)
import static org.junit.jupiter.api.Assertions.assertEquals;
public class UsersResourceTest extends JerseyTest {
@Override
protected Application configure() {
return new ResourceConfig()
.register(UsersResource.class)
.register(JacksonFeature.class);
}
@Test
public void testGet() {
Response response = target().path("users/1").request().get(Response.class);
assertEquals(200, response.getStatus());
assertEquals("{\"data\":{}}", response.readEntity(String.class));
}
}
Note, you can use both JUnit 4 and 5 in the same test. Quite cool isn't.
Thanks for the suggestion @ValentinTrinque. Indeed, it's very nice that JUnit 5 has backward compatability.
However it doesn't solve the issue. Yes, junit vintage allows you to run JUnit 4 tests on the JUnit 5 platform. And yes, you can use any assertion library you want (Truth, AssertJ, Junit4 or 5 etc). These aren't tied to any junit version/platform, they all just throw some sort of AssertionFailed exception when a condition isn't met.
However by continuing to use the JUnit 4 test API you lose out on the all the other nice JUnit 5 features, in particular the new extension model that allows multiple extensions to be applied, and for dependencies to be injected into methods/constructors. ( plus many other features)
Extending a class to get features isn't a great way to do things as of course you can only extend one class so inheritance should be avoided where possible.