Jersey 测试在使用 UriInfo 时给出 NullPointerException
Jersey test gives NullPointerException when using UriInfo
我正在创建一个应该能够使用 REST 创建帐户的应用程序 api。当我写 AccountController.java
class 时一切正常。我用邮递员来验证我得到了正确的回复。
所以我的 AccountController.java
工作正常,但我用它编写的单元测试不起作用。当执行单元测试时,它 return 是一个 NullPointerException
,这会导致 REST API 中的 InternalServerError。在调试时我发现如果我在 AccountController.java
和 return Response.ok() 中删除 UriInfo 的使用而不是创建测试成功。
所以我的问题是。我如何正确 test/mock 一个 returns 和 URI 的方法?
以下是所有相关的 classes 和依赖项。 Account.java
class 在另一个包中。但是主应用程序和包含 Account.java
的项目都是同一个父 pom 的一部分。我不确定这是否与我的问题相关。
AccountController.java
@Stateless
@Path("/accounts")
public class AccountController {
@Inject
private AccountService accountService;
@Context
private UriInfo uriInfo;
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response create(Account account) {
final Account newAccount = accountService.create(account);
System.out.println("Pre uriinfo message");
//Removing this line and returning Response.ok() removes the exception
final URI uri = uriInfo.getAbsolutePathBuilder().path(newAccount.getId() + "").build();
System.out.println("Post uriinfo message");
return Response.created(uri).entity(newAccount).build();
}
}
AccountControllerTest.java
@RunWith(MockitoJUnitRunner.class)
public class AccountControllerTest extends JerseyTest {
@Mock
private AccountService service;
@Override
protected Application configure() {
final ResourceConfig config = new ResourceConfig(AccountController.class);
config.register(new AbstractBinder() {
@Override
protected void configure() {
bind(service).to(AccountService.class);
}
});
return config;
}
@Test
public void createUserTest() throws Exception {
final Account testAccount = new Account("testName", "test@mail.nl");
when(service.create(testAccount))
.thenReturn(testAccount);
System.out.println("Create account test");
//Create a new Account
final Response correctResult = target("/accounts")
.request(MediaType.APPLICATION_JSON)
.post(Entity.json(testAccount));
Assert.assertEquals(HTTP_CREATED, correctResult.getStatus());
Assert.assertEquals(testAccount, correctResult.readEntity(Account.class));
}
}
Account.java
@Entity
@XmlRootElement
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(nullable = false)
private String fullName;
@Column(unique = true, nullable = false)
private String mail;
private boolean active;
public Account() { }
public Account(String fullName, String mail) {
this.fullName = fullName;
this.mail = mail;
}
//Contains getters&setters
}
测试依赖项
<!-- jersey version for "Jersey Media Json Jackson" & "Jersey Test Framework Provider Jetty" -->
<properties>
<jersey.version>2.26-b03</jersey.version>
</properties>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.9.0</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.test-framework.providers/jersey-test-framework-provider-jetty -->
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-jetty</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-jaxrs -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.1.4.Final</version>
<scope>test</scope>
</dependency>
所以我终于想通了。
AccountController.java
这一行的某处抛出了 NullPointerException
:
final URI uri = uriInfo.getAbsolutePathBuilder().path(newAccount.getId() + "").build();
这只发生在使用我的 JerseyUnitTest 时,所以我猜 Jersey 必须改变 UriInfo
.
的某些行为
最终我通过覆盖 Account.java
中的 equals
解决了问题。
我正在创建一个应该能够使用 REST 创建帐户的应用程序 api。当我写 AccountController.java
class 时一切正常。我用邮递员来验证我得到了正确的回复。
所以我的 AccountController.java
工作正常,但我用它编写的单元测试不起作用。当执行单元测试时,它 return 是一个 NullPointerException
,这会导致 REST API 中的 InternalServerError。在调试时我发现如果我在 AccountController.java
和 return Response.ok() 中删除 UriInfo 的使用而不是创建测试成功。
所以我的问题是。我如何正确 test/mock 一个 returns 和 URI 的方法?
以下是所有相关的 classes 和依赖项。 Account.java
class 在另一个包中。但是主应用程序和包含 Account.java
的项目都是同一个父 pom 的一部分。我不确定这是否与我的问题相关。
AccountController.java
@Stateless
@Path("/accounts")
public class AccountController {
@Inject
private AccountService accountService;
@Context
private UriInfo uriInfo;
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response create(Account account) {
final Account newAccount = accountService.create(account);
System.out.println("Pre uriinfo message");
//Removing this line and returning Response.ok() removes the exception
final URI uri = uriInfo.getAbsolutePathBuilder().path(newAccount.getId() + "").build();
System.out.println("Post uriinfo message");
return Response.created(uri).entity(newAccount).build();
}
}
AccountControllerTest.java
@RunWith(MockitoJUnitRunner.class)
public class AccountControllerTest extends JerseyTest {
@Mock
private AccountService service;
@Override
protected Application configure() {
final ResourceConfig config = new ResourceConfig(AccountController.class);
config.register(new AbstractBinder() {
@Override
protected void configure() {
bind(service).to(AccountService.class);
}
});
return config;
}
@Test
public void createUserTest() throws Exception {
final Account testAccount = new Account("testName", "test@mail.nl");
when(service.create(testAccount))
.thenReturn(testAccount);
System.out.println("Create account test");
//Create a new Account
final Response correctResult = target("/accounts")
.request(MediaType.APPLICATION_JSON)
.post(Entity.json(testAccount));
Assert.assertEquals(HTTP_CREATED, correctResult.getStatus());
Assert.assertEquals(testAccount, correctResult.readEntity(Account.class));
}
}
Account.java
@Entity
@XmlRootElement
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(nullable = false)
private String fullName;
@Column(unique = true, nullable = false)
private String mail;
private boolean active;
public Account() { }
public Account(String fullName, String mail) {
this.fullName = fullName;
this.mail = mail;
}
//Contains getters&setters
}
测试依赖项
<!-- jersey version for "Jersey Media Json Jackson" & "Jersey Test Framework Provider Jetty" -->
<properties>
<jersey.version>2.26-b03</jersey.version>
</properties>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.9.0</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.test-framework.providers/jersey-test-framework-provider-jetty -->
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-jetty</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jboss.resteasy/resteasy-jaxrs -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.1.4.Final</version>
<scope>test</scope>
</dependency>
所以我终于想通了。
AccountController.java
这一行的某处抛出了 NullPointerException
:
final URI uri = uriInfo.getAbsolutePathBuilder().path(newAccount.getId() + "").build();
这只发生在使用我的 JerseyUnitTest 时,所以我猜 Jersey 必须改变 UriInfo
.
最终我通过覆盖 Account.java
中的 equals
解决了问题。