使用UriInfo时,Jersey测试会给出NullPointerException

时间:2017-09-14 12:22:07

标签: java rest junit jersey mockito

我正在创建一个应该能够使用REST api创建帐户的应用程序。当我写AccountController.java课时,一切正常。我用邮递员来验证我得到了正确的答复。

所以我的AccountController.java正常工作,但我用它编写的单元测试不起作用。执行单元测试时,它返回NullPointerException,导致REST API中出现InternalServerError。在调试时我发现如果我在AccountController.java中删除了UriInfo的使用并返回Response.ok()而不是创建测试就成功了。

所以我的问题是。我如何正确测试/模拟返回和URI的方法?

Bellow是所有相关的类和依赖项。 Account.java类在另一个包中。但是作为包含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>

1 个答案:

答案 0 :(得分:0)

所以我终于明白了。 在AccountController.java的这一行的某个地方,NullPointerException被抛出:

final URI uri = uriInfo.getAbsolutePathBuilder().path(newAccount.getId() + "").build();

这只发生在使用我的JerseyUnitTest时,所以我猜Jersey应该改变UriInfo的某些行为。

最终我通过覆盖equals中的Account.java解决了这个问题。