如何使用Arquillian测试RESTful方法?

时间:2013-08-21 14:45:17

标签: unit-testing rest java-ee jboss-arquillian

我有一组用于在项目中使用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。这是因为测试用例中的空响应。为什么会这样? DB配置正确。

1 个答案:

答案 0 :(得分:8)

arquillian测试可以运行两种模式:容器内和客户端模式。 HTTP接口只能在客户端模式下进行测试(从未尝试过扩展,只使用了香草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() {
    }
}

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