I am developing a light weight server App with a RESTful api implemented with Jersey 2.12 and Jackson 2.
I am writing tests while developing using JUnit and JerseyTest. I know that my Jersey Resources work as expected including the marshalling from and to JSON because I tested them manually with the PostMan Chrome plugin.
My GET tests with query parameters work well too, based on the example in the Jersey documentation Here is a simplified (I have left out boilerplate code to make the idea clearer) example of a test I'd like to write:
import static org.junit.Assert.assertTrue;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import com.acme.api.rest.SessionsEndPoint;
import com.acme.api.rest.beans.UserCredentialsBean;
public class TestSession extends JerseyTest {
@Override
protected Application configure() {
return new ResourceConfig(SessionsEndPoint.class);
}
@Test
public void test() {
UserCredentialsBean userCredentialsBean = new UserCredentialsBean();
userCredentialsBean.setUserId("alice");
userCredentialsBean.setPassword("secret");
WebTarget theTarget = target("sessions/login");
Response response = theTarget.request().post( Entity.entity(UserCredentialsBean.class, "application/json"));
assertTrue(true);
}
}
The basic problem I have is that I cannot find any documentation on how to properly use the WebTarget class for post requests. the WebTarget theTarget is constructed correctly but the line:
Response response = theTarget.request().post( Entity.entity(UserCredentialsBean.class, "application/json"));
does not work.
As I understand the WebTarget class is fairly new in the JerseyTest framework. Is there anybody who can point me at any recent documentation, examples, or just explain here how I can get this to work?
I did do a lot of googling before I posted my question here, but after checking back my eyes suddenly fell on this Related Question. I did search on SO several times but never found this question. Anyway, here's the solution to my problem:
I started implementing as explained in the accepted answer and got it to work quickly.
Then I decided that you it should be possible to avoid using JSON string representations at all, and I got that to work to.
The code above works if modified as follows:
import static org.junit.Assert.assertTrue;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import com.acme.api.rest.SessionsEndPoint;
import com.acme.api.rest.beans.UserCredentialsBean;
public class TestSession extends JerseyTest {
@Override
protected Application configure() {
return new ResourceConfig(SessionsEndPoint.class);
}
@Test
public void test() {
UserCredentialsBean userCredentialsBean = new UserCredentialsBean();
userCredentialsBean.setUserId("alice");
userCredentialsBean.setPassword("secret");
LoginResponseBean loginResponseBean =
target("sessions/login")
.request(MediaType.APPLICATION_JSON_TYPE)
.post(
Entity.entity(
userCredentialsBean,
MediaType.APPLICATION_JSON_TYPE
),
LoginResponseBean.class
);
assertTrue(
loginResponseBean.isSuccess()
&&
loginResponseBean.getToken().length()==36
);
}
}
LoginResponseBean is a plain Java Bean. Just getters and setters and a default constructor.
Marshalling to- and from JSON is done by the framework, either by moxy or jackson as the JSON provider.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With