我正在创建一个应该能够使用REST api创建帐户的应用程序。当我写AccountController.java
课时,一切正常。我用邮递员来验证我得到了正确的答复。
所以我的AccountController.java
正常工作,但我用它编写的单元测试不起作用。执行单元测试时,它返回NullPointerException
,导致REST API中出现InternalServerError。在调试时我发现如果我在AccountController.java
中删除了UriInfo的使用并返回Response.ok()而不是创建测试就成功了。
所以我的问题是。我如何正确测试/模拟返回和URI的方法?
Bellow是所有相关的类和依赖项。 Account.java
类在另一个包中。但是作为包含Account.java
的项目的主应用程序都是同一父pom的一部分。我不确定这是否与我的问题相关。
@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();
}
}
@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));
}
}
@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>
答案 0 :(得分:0)
所以我终于明白了。
在AccountController.java
的这一行的某个地方,NullPointerException
被抛出:
final URI uri = uriInfo.getAbsolutePathBuilder().path(newAccount.getId() + "").build();
这只发生在使用我的JerseyUnitTest时,所以我猜Jersey应该改变UriInfo
的某些行为。
最终我通过覆盖equals
中的Account.java
解决了这个问题。