我有一组用于在项目中使用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配置正确。
答案 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() {
}
}
这有时甚至是必要的,因为某些扩展(如持久性)无法在客户端模式下运行。