3

我有一组类可以在项目中使用 REST 方法。它们看起来像这样:

@Path("customer/")
@RequestScoped
public class CustomerCollectionResource {

    @EJB
    private AppManager manager; // working with DB

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response list(@QueryParam("email") String email) {
        final List<Customer> entities = manager.listCustomers(email);
        // adding customers to result
        return Response.ok(result).build();
    }
}

之后我写了测试方法:

@RunWith(Arquillian.class)
public class CustomerResourceTest { 

@Deployment
public static WebArchive createTestArchive() {
        return ShrinkWrap.create(WebArchive.class, "test.war")
        // Adding omitted                                
        //.addClasses(....)                 
    }   

    @Test @GET @Path("projectName/customer") @Consumes(MediaType.APPLICATION_JSON)
    public void test(ClientResponse<List<Customer>> response) throws Exception {
    assertEquals(Status.OK.getStatusCode(), response.getStatus());      
    }
}

尝试运行此测试时,我得到 NullPointerException。这是因为测试用例中的空响应。为什么会这样?数据库配置正确。

4

1 回答 1

8

arquillian 测试可以运行两种模式:容器内模式和客户端模式。HTTP 接口只能在客户端模式下测试(从未尝试过扩展,只使用 vanilla Arquillian)。

默认情况下,测试方法在容器上下文中执行,由 arquillian 测试运行器 servlet 调用。

@RunWith(Arquillian.class)
public class CustomerResourceTest { 

    @EJB SomeBean bean; // EJBs can be injected, also CDI beans, 
                        // PersistenceContext, etc

    @Deployment
    public static WebArchive createTestArchive() {
        return ShrinkWrap.create(WebArchive.class, "test.war")
        // Adding omitted                                
        //.addClasses(....)                 
    }

    @Test
    public void some_test() {
        bean.checkSomething();
    }
}

在客户端模式下,测试方法在容器外运行,因此您无法访问注入到测试类中的 EJB、EntityManager 等,但您可以为测试方法注入 URL 参数。

@RunWith(Arquillian.class)
public class CustomerResourceTest { 

    // testable = false here means all the tests are running outside of the container
    @Deployment(testable = false) 
    public static WebArchive createTestArchive() {
        return ShrinkWrap.create(WebArchive.class, "test.war")
        // Adding omitted                                
        //.addClasses(....)                 
    }   

    // baseURI is the applications baseURI. 
    @Test
    public void create_account_validation_test (@ArquillianResource URL baseURI) {
    }

您可以使用此 URL 参数构建 URL,以使用您拥有的任何方法调用您的 HTTP 服务,例如新的 JAX-RS 客户端 API。

您还可以混合使用两种模式:

@RunWith(Arquillian.class)
public class CustomerResourceTest { 

    @EJB SomeBean bean;

    @Deployment
    public static WebArchive createTestArchive() {
        return ShrinkWrap.create(WebArchive.class, "test.war")
    }

    @Test
    @InSequence(0) 
    public void some_test() {
        bean.checkSomething();
    }

    @Test
    @RunAsClient // <-- this makes the test method run in client mode
    @InSequence(1)
    public void test_from_client_side() {
    }
}

这有时甚至是必要的,因为某些扩展,如持久性不能在客户端模式下运行。

于 2013-08-22T15:53:16.220 回答