Testing Rest Api methods - java

I'have to test the functions in rest api class that i created, I'm unable to get the functions of the created api class inside the test class, I haven't do the testing coding before. I need some guides to follow .
#POST
#Produces("text/plain")
#Path("/notifications/login/")
#HeaderParam("encoded")
Response login(#HeaderParam("encoded") String encoded, #QueryParam("tenantId") String tenantId) throws NotificationManagementException;
Its a function that i created, im not giving whole function body here, i need to know how to test this function. I'm giving a request call in javascript.

Unless there is some reason why you really don't want to, you could make the method public, and then you would be able to see it inside the test class.
i.e.
public Response login(...)
In the test you can then make a new instance of the class and call the method normally.
e.g.
#Test
public void shouldDoSomething(){
SomeClass someClass = new SomeClass();
someClass.login(...);
//some assertions or verifications
}

Two ways:
Use Postman to send post request.
Follow Spring-rest-client to create a rest client for test.

You can test with Postman a great chrome extension tool for REST based APIs. Run your server and hit the request from Postman. The image shows how to make a request.

Related

How to mock response of an external API called from within an internal API integration test

I am writing integration tests for an application that uses an internal REST API to perform an action; all Java.
In the API, there is a POST method that calls upon an external API. In the test, I need to send a request to my API to perform an action.
The problem is, I do not want to send real requests to the external API when running the integration tests.
How can I mock the response of the external API call?
Is there a way I can still send a POST request to my API (mocked or otherwise) within my test, but use a mocked response for the external call performed in the Java POST method?
I've done this as follows: create a service layer that makes the API calls to external services. I built mine on Spring's RestTemplate but you could use whatever library to make calls. So it'll have methods like get() or post().
Then I use Postman to perform some requests against the external API and save the responses in files and add these files to my project.
Finally, in my tests, I mock out the calls to my little API service layer so that instead of going to the external API, it reads from the test files I saved previously. This runs the code under test with known payloads that came from the external API, but without requiring a connection to it during the test, and which won't change until I update the responses in the files myself.
I use EasyMock but any mocking library will work. Here's an example of what a test looks like.
#Test
public void test_addPhoneToExternalService() {
// Mock my real API service.
ApiService mockApiService = EasyMock.createMock(ApiService.class);
// Construct my service under test using my mock instead of the real one.
ServiceUnderTest serviceUnderTest = new ServiceUnderTest(mockApiService);
// Expect the body of the POST request to look like this.
Map<String, Object> requestBody = new HashMap<String, Object>() {{
put("lists", 0);
put("phone", "800-555-1212");
put("firstName", "firstName");
put("lastName", "lastName");
}};
// Read the response that I manually saved as json.
JsonNode expectedResponse = Utils.readJson("response.json");
expect(mockApiService.post(anyObject(),
eq("https://rest.someservice.com/api/contacts"), eq(serialize(requestBody))))
.andReturn(expectedResponse);
EasyMock.replay(mockApiService);
// Call the code under test. It ingests the response
// provided by the API service, which is now mocked,
// and performs some operations, then returns a value
// based on what the response contained (for example,
// "{\"id\":42}").
long id = serviceUnderTest.addPhone("firstName", "lastName", "800-555-1212");
Assert.assertThat(id, is(42L));
EasyMock.verify(mockApiService);
}
Hope that helps!

javax.ws.rs REST testing by target - where to get or set the server address?

Where I am unit testing a REST function created in javax.ws.rs, and using target() for URL, as in https://stackoverflow.com/a/28726499/715269, and I don't know how to set the server part of the URL.
If I set it in hard way, the test will run only in one surrounding, on release server, for example. But normally, I run the application on any server, and API functions work on different servers, depending on where I had launch the application.
If I won't set any server for target:
String targetUrl = "/api/v1/documentTypes";
try (Response response = target(targetUrl).request().post(Entity.json(simpleJson))) {
And look for the URI in response, I see some server part set there (http://localhost:9998/), but I don't know where is it from, and this imitated server does not know the API function from targetUrl string.
How should I write this part of unit test, so as to be run universally?
I think that maybe overrode configure() method could help, but I am not sure.
I have found!
The test class extends from the JerseyTest class.
public class DocumentTypesTest extends JerseyTest {
That class has configure() method, that must be overrode:
#Override
protected Application configure() {
return new ResourceConfig(DocumentTypes.class);
}
And the new overriden method should return config of the class where the tested API functions lie.
It could cause some misunderstanding: Your API function could be grouped by 'value=' from several classes. And you (as I did) can create the same test class for all API functions of the group. That won't work!. You should make separate test class for every API methods' class.

creating a simple SOAP server

I have a Java project which talks to a SOAP server. I need to debug my application on my local machine. I do not want my application to get connected to the main SOAP server. I need to have a fake SOAP web server to which my application gets connected.
I want it to be as simple as possible. So, I want the server to returns a specific response for any request it receives! Is there any way by which I can reach my goal?
You don't have to build a real server for testing/debuging your code.
you can use a Mock.
This way:
you don't change your real code,
the testing code is reusable,
you don't need to implement logic, just tell it what is the expected call results
you test only your own class (there might be bugs in the soap server)
The most popular mocking framework is Mockito.
It can be as simple as:
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
#Test
public void test1() {
// create mock
MyClass test = mock(MyClass.class);
// define return value for method createSoapCall()
when(test.createSoapCall()).thenReturn(43);
// use mock in test....
assertEquals(test.createSoapCall(), 43);
}
tutorial:
http://www.vogella.com/tutorials/Mockito/article.html
official site:
http://site.mockito.org/

Find out which endpoint sent a REST call

I'm trying to create a visualisation of REST calls among several internal and external services/servers. I'd like to know which endpoint called which other endpoint. I figured that the only way to do this is to do this on the caller side, because the receiver does not have any information about the caller endpoint.
Here's my thinking:
I create an object like RestTemplate and call the method.
I create an Interceptor or something like that, which will extract the information from the RestTemplate.
My problem is that I'm not sure how to find out which REST endpoint called the RestTemplate method. The RestTemplate (or other similar object) call could be called in nested methods, so for example the endpoint could invoke a private method, which then calls the external service itself.
Is there any way how to get this information? Or am I maybe just thinking too hard and there is an easier way to do this?
Example:
#GetMapping("/hello")
public String hello() {
methodThatCallsOtherEndpoint("something.com/weather"); // this method inside itself calls an endpoint
logRestCall("localhost:8000/hello", "something.com/weather"); // how do I do this automatically without having to type it myself?
return "hello";
}
Thanks for any help.
If these services/servers have a static IP you can possibly, tag them by their IP address?
You can use Spring Sleuth to trace the relationship between different REST calls.

How do I unit test code which calls the Jersey Client API?

I wrote code which calls the Jersey client API which in turn calls a web service which is out of my control. I do not want my unit test to call the actual web service.
What is the best approach for writing a unit test for code which calls the Jersey client API? Should I use the Jersey server API to write a JAX-RS web service and then use the Jersey Test Framework for the unit test? Or should I mock out the Jersey web service calls? I have access to JMock. Or should I try another approach?
During my research, I found this discussion describing various options, but I did find a complete solution. Are there any code examples available showing a suggested JUnit approach? I could not find any in the Jersey documentation.
Here is the relevant source code:
public String getResult(URI uri) throws Exception {
// error handling code removed for clarity
ClientConfig clientConfig = new DefaultClientConfig();
Client client = Client.create(clientConfig);
WebResource service = client.resource(uri);
String result = service.accept(accept).get(String.class);
return result;
}
Here are examples of test code I would like to pass. I would like to test (1) passing in a valid URI and getting a valid string back and (2) passing in an invalid (for whatever reason -- unreachable or unauthorized) URI and getting an exception back.
#Test
public void testGetResult_ValidUri() throws Exception {
String xml = retriever.getResult(VALID_URI);
Assert.assertFalse(StringUtils.isBlank(xml));
}
#Test(expected = IllegalArgumentException.class)
public void testGetResult_InvalidUri() throws Exception {
retriever.getResult(INVALID_URI);
}
Everything above is the simple description of what my code does. In reality, there is a layer on top of that that accepts two URIs, first tries calling the first URI, and if that URI fails then it tries calling the second URI. I would like to have unit tests covering (1) the first URI succeeds, (2) the first URI fails and the second URI succeeds, and (3) both URIs fail. This code is sufficiently complex that I want to test these different scenarios using JUnit, but to do this I either need to run actual stand-in web services or mock out the Jersey client API calls.
Try to use Mockito or Easymock for mocking service calls. You need to mock only these methods which are actually used - no need to mock every method. You can creat mock object for WebResource class, then mock accept method call.
In #BeforeClass/#Before JUnit test method write something like (Mockito example)
WebResource res = mock(WebResource.class);
when(res.accept(something)).thenReturn(thatWhatYouWant);
Then in your tests you can use res object as if it was real object and call mock method on it. Instead of returning value you can also throw exceptions. Mockito is pretty cool.
Typically what you are really after is "does the way I use the Jersey Client DSL produce a request to the correct URL with the correct payload and URL parameters". Testing this with Mockito is really verbose and the setup code will usually end up looking something like this:
when(authentication.queryParam(eq("sa"), anyBoolean())).thenReturn(testAuthentication);
when(testAuthentication.resolveTemplate("channel", "smf")).thenReturn(testAuthentication);
when(testAuthentication.request(
MediaType.APPLICATION_JSON_TYPE)).thenReturn(mockRequestBuilder);
when(mockRequestBuilder.post(any(Entity.class))).thenReturn(mockResponse);
when(mockResponse.readEntity(ResponseWrapper.class)).thenReturn(successfulAuthResponse());
And this is basically just for a single REST request. It's overly verbose, and instead of testing the hoped outcome you are just replicating the steps you think are correct in using the Jersey Client DSL.
Instead of the above, I would aim for mocking a simple service. For this I've used WireMock which starts a Jetty server and where I can stub things like "expect a request to this URL, respond with this message and verify that the payload is this".
I know this is edging on an integration test and it is a bit slower than just using Mockito but I value testing the real outcome and I value the readability of the tests way more in this case.
Setup for a WireMock based Jersey Client test looks something like this:
#Test
public void exactUrlOnly() {
stubFor(get(urlEqualTo("/some/thing"))
.willReturn(aResponse()
.withHeader("Content-Type", "text/plain")
.withBody("Hello world!")));
assertThat(testClient.get("/some/thing").statusCode(), is(200));
assertThat(testClient.get("/some/thing/else").statusCode(), is(404));
}
Just implement a work-alike service and in your unit test setup start the service using HttpServerFactory.

Categories

Resources