Reputation: 3322
I have a set of classes to work with REST methods in project. They look like this:
@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();
}
}
After that I've wrote test method:
@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());
}
}
And I get NullPointerException when trying to run this test. It's because of empty response in test case. Why is this happens? DB is configured properly.
Upvotes: 3
Views: 7717
Reputation: 2464
There are two modes an arquillian test can run: in-container and client mode. HTTP interfaces can be tested only in client mode (never tried the extensions, only used vanilla Arquillian for this).
By default the test methods executed in the context of the container, called by the arquillian test runner 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();
}
}
In client mode, the test methods are running outside of the container, so you don't have access to EJBs, EntityManager, etc injected into the test class, but you can inject an URL parameter for the test method.
@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) {
}
You can use this URL parameter to build URLs to call your HTTP service using whatever method you have, like the new JAX-RS client API.
You can also mix the two modes:
@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() {
}
}
This is sometimes even necessary, because some extensions, like persistence cannot run in client mode.
Upvotes: 8