Jersey client testing - java

I have a Jersey client which performs post request to some black box service.
Also I have POJO mapping feature enabled.
I have integration tests already, they are calling real black box service.
Now I need to test my application without calling real black box service.
My question is: how can I test this Jersey client? I mean: how can I test Jersey client without calling real black box service?Maybe there is some possibility to mock JSON response in tests?
Environment: jersey-client and jersey-json versions - 1.19.1.

You can log the request using LoggingFilter to make sure your requests are according to your estimate. For running your test, you can use http://mockable.io/.
P.S. Do not forget to replace the Webtarget URL with MockableIO's URL.

You can try Karate which has recently introduced a way to create simple mocks for JSON responses. Here is an example:
https://gist.github.com/ptrthomas/35ef9d40623cbeade7388b2cbb29a3b1
While the above example is a "smart" mock, it is very easy to create hard-coded mocks, here is an example: https://github.com/intuit/karate/blob/master/karate-netty/src/test/java/com/intuit/karate/mock/_mock.feature
You can easily read files from JSON by using the read keyword.

I have performed an investigation concerning my question. Mentioned investigation resulted in such facts:
I haven't found features/mechanisms/etc. to test Jersey client without real calls to the server (in my case - black box service).
Jersey test framework provides features for testing Jersey server, but there are no features for testing Jersey client
The only one solution for testing client without server is to refactor my code in following way: split logic into two phazes. First phaze: get JSON response using Jersey. Second phaze: get JSON response (which we get in first phaze) and transform it into desired object. In general you'll have next code as a result:
Class< String > jsonResposeClass = String.class;
String jsonResponse = post( yourRequest, jsonResposeClass );
ObjectMapper mapper = new ObjectMapper();
YourResponseBean bean = mapper.readValue( jsonResponse , responseClass );
The solution above will give you a possibility to use mocking libraries like Mockito and mock method which performs post request.
If you have found any other solution/feature/special mechanism/etc which can also help in such kind of situation - please share :)

Related

Mocking inbound Jax-RS Response with Entity

I am trying to unit test a class that uses Jersey 2 Client + Moxy to call a REST service. I want to mock the response, which contains a large JSON object. The code is structured in such a way that I can override/mock the following method:
protected Response doPost(String path, Entity<?> entity) {
Invocation.Builder invocationBuilder = getRestInvocationBuilder(path);
Response response = invocationBuilder.post(entity);
return response;
}
I would like to somehow inject some example JSON data (ideally from a file) into the Response at this point, prior to readEntity() being called, so that I can test that the JSON data is correctly unmarshalled into the target object.
Is there any way to do this? Note that this is for unit testing and therefore I'm not interested in running a local server or other integration testing techniques.
I'm aware similar questions have been asked, but many seem out of date or have incomplete solutions. The closest solution suggested is to mock the readEntity() method of the Response, this will not work for me because it would involve creating an object of the desired type to return, rather than creating one from the example JSON data.

How test javax Response.readEntity(Class<T> type)?

We're using javax.ws.rs.core.Response.readEntity(Class type) to parse JSON responses into POJOs. I want to write tests to assure that the entity is correctly mapped into the POJO - so if a boolean "valid" is true in the json, it is also true in the POJO - and vice versa.
I cannot figure out how to do it. Any ideas or tips?
I want to write tests to assure that the entity is correctly mapped into the POJO
If all you want to test is that the POJO is mapped correctly, and you are using Jackson as the JSON provider, you can simply use the ObjectMapper to deserialize the JSON. This is how Dropwizard recommends testing models
final ObjectMapper mapper = new ObjectMapper();
POJO pojo = mapper.readValue(jsonString, POJO.class);
// assertions
Testing marshalling is one of those things in jax-rs services that are not easy to test with plain junit tests. For instance, how can you ensure you did not forget an annotation #Path or #QueryParam, so that your junit test calling the method succeeds, but actually calling the service fails.
Arquillian provides a solution for those tests. Essentially, Arquillian enables executing tests in a running javaee container. The test setup includes building your war, and deploying your application. This way, you can test all elements of your stack, and make sure all goes together: marshalling, request routing, http filters,...
If you are using the jersey jax-rs stack, you can alternatively use JerseyTest.
Arquillian is more complete, since it enables testing with multiple containers (even selenium support) and does not tie you with a jax-rs implementation.

How do you test multiple REST Requests?

//1) Request
//Given
String req = new ObjectMapper().writeValueAsString(new Request("2016-11-15"));
//set HttpHeaders
//set HttpEntity
// When
ResponseEntity responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
Is there a convenient way of unit testing multiple REST API requests? I would like to create a bunch of requests to submit to a queue which will then be processed. The request are to have different HttpHeaders and different ReportRequestBody.
I have done single request unit testing and are able to capture statuses using ResponseEntity.
Can anyone point me to some examples or documentation on best practices. I am a beginner and I am not sure where to start with multiple requests.
For testing requests and responses in DjangoRest you can use following tools or ways....
You can use print statement to see what is being printed and then you can interpret print results accordingly.
You can use Debugger of any IDE such as PyCharm.
You can use Postman to test your API as it gives you whole idea of
the responses you are getting.
For more information on requests you can visit here
Yes I would certainly say this is more of an integration/load test scenario. You may want to look into using Jmeter with Junit tests. You can use its JUnit Request Sampler. Here was a post on stackoverflow to a different question, but it provides a link to a helpful article. The post was Spring load testing . Here is also a link to the article directly https://www.blazemeter.com/blog/how-use-junit-jmeter. This should get you heading in the right direction.

Servlet Testing

I am using the ServletTester class provided by Jetty to test one of my servlets.
The servlet reads the the body of the request using InputStream.read() to construct a byte[] which is the decoded and acted on by the servlet.
The ServletTest class provides a method getResponses(ByteArrayBuffer) but I'm unsure how to create one of these in the correct format since it would also need to contain things like headers (e.g. "Content-Type: application/octet-stream).
Can anyone show me an easy way to construct this, preferably using an existing library so that I can use it in a similar way to the HttpTester class.
If there is a "better" way to test servlets (ideally using a local connector rather than via the tcp stack) I'd like to hear that also.
Many thanks,
Why use a mock at all? Why not test the servlet by running it in jetty?
Servlet servlet = new MyServlet();
String mapping = "/foo";
Server server = new Server(0);
Context servletContext = new Context(server, contextPath, Context.SESSIONS);
servletContext.addServlet(new ServletHolder(servlet), mapping);
server.start();
URL url = new URL("http", "localhost", server.getConnectors()[0].getLocalPort(), "/foo?bar");
//get the url...assert what you want
//finally server.stop();
Edit: Just wanting to reassure people that this is very fast. Its also a very reliable indicator of what your code will actually do, because it is in fact doing it.
Spring MVC provides a small set of "mock" classes for the various javax.servlet interfaces, such as HttpServletRequest, HttpSession, and so on. This makes it easy to unit test the likes of a servlet, you just inject mocks into the e.g. doGet() method.
Even if you don't use Spring itself on the server, you can still use the mock from the library, just for your tests.
You can use HttpClient to simplify testing somewhat. Take a look at the following article:
http://roberthanson.blogspot.com/2007/12/testing-servlets-with-junit.html
That in combination with servlet tester should give you what you want unit test wise.

How can I unit test a servlet with a request that just consists of xml content

I'm trying to unit test a java WFS web service implementation. The service can accept requests containing KVP params such as:
http://www.someserver.com/wfs&SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&TYPENAME=InWaterA_1M
or it can also accept a request containing an XML fragment such as
<?xml version="1.0" ?>
<GetFeature version="1.1.0" service="WFS" maxFeatures="10000"
xmlns="http://www.opengis.net/wfs"
xmlns:myns="http://www.someserver.com/myns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wfs ../wfs/1.1.0/WFS.xsd">
<Query typeName="myns:InWaterA_1M"/>
</GetFeature>
I'm testing the KVP way using ServletUnit, which is straight forward:
ServletUnitClient sc = servletRunner.newClient();
WebRequest request = new PostMethodWebRequest( "http://www.someserver.com/wfs
request.setParameter( "SERVICE", "WFS );
...
request.setParameter( "TYPENAME" "InWaterA_1M" );
sc.getResponse( request);
I can't figure out how to create a corresponding request for the XML type of request though. Any ideas? I'd rather not have to use another testing framework library unless absolutely necessary.
You can create a do the following:
Create a XML of the request you want..
Create a MockHttpServletRequest
API: http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/mock/web/MockHttpServletRequest.html
Call setContent(xml); and setContentType("text/xml");
Call your servlet method directly. e.g. someServlet(mockReq,mockRes);
This way there is no need to fire up the servlet container while jUnit testing...
From a quick look at the docs, it seems that ServletUnitClient can support POST requests, as well as GET requests with KVP style arguments, like you are using now: http://httpunit.sourceforge.net/doc/tutorial/task1editor-form.html
Request with XML works like posting an HTML form, only that you don't necessarily have the HTML UI in front of it.
However, I would probably break out the unit testing of the XML parsing to a separate test, and not test it explicitly through the servlet. The servlet is acting as an HTTP frontend for the XML parsing and other parts of the WFS service, and you should unit test those parts separately (perhaps you're already doing that, disregard this part in that case).
In my experience, testing the HTTP/frontend of a service is usually the least important part, the logic behind it is much more likely to break, and therefore more important to test. Also, testing the service logic separately from the frontend often forces you to use a better design.
Of course, if you have to the time, or the frontend itself involves a lot of logic, you should unit test that part as well.

Categories