Over a million developers have joined DZone.

JUnit Testing REST Services and Spring MVC

· Java Zone

Microservices! They are everywhere, or at least, the term is. When should you use a microservice architecture? What factors should be considered when making that decision? Do the benefits outweigh the costs? Why is everyone so excited about them, anyway?  Brought to you in partnership with IBM.

For people in a hurry get the latest code in Github and run “mvn test”

Introduction

There is a good comparison of Webservices and REST here. REST Services are a point-to-point communication over HTTP using XML. There are a couple of good discussions around this in this Stackoverflow article and Toolbox article.

Spring MVC is a good framework to develop REST Services. In this blog I will show you how JUnit tests REST Services. I started reading a few materials around spring-test-mvc and testing Spring MVC REST Services. The GET was working, but the POST was not working. You can see that in the JUnit test in the sample. Next I started trying MockHttpServletRequest/ MockHttpServletResponse there is a good material in Stacktrace on JUnit testing Spring MVC and REST Services. I followed the steps, but it still did not work. It was throwing an exception related to PropertyEditor. There was a good article on how to get this error fixed. Once I put in this fix it started working.

Details: JUnit for Spring MVC and REST Services

In this example, we developed a REST Service and Spring MVC, which has 5 operations, getAll, findbyId, create, update, delete and we write a JUnit test to call each operation and assert for the expected value.

Based on TDD, we write the test first and for all the 5 methods.  Then we assert for expected values as below,

@Test
public void testGetLoanRequest() throws Exception {
LoanRequest loanRequest1 = new LoanRequest();
loanRequest1.setId(2);
ibatisTemplate.insert("GoSmarter.loanRequestInsert", loanRequest1);
requestMock.setMethod("GET");
requestMock.setRequestURI("/loanrequests/2");
handlerAdapter.handle(requestMock, responseMock, loanRequestController);
logger.debug(responseMock.getContentAsString());
LoanRequest loanRequest = mapper.readValue(responseMock.getContentAsString(), LoanRequest.class);
assertNotNull(loanRequest);
assertEquals(loanRequest.getId(), Integer.valueOf(2));
}

@Test
public void testListLoanRequest() throws Exception {
LoanRequest loanRequest1 = new LoanRequest();
ibatisTemplate.insert("GoSmarter.loanRequestInsert", loanRequest1);
loanRequest1 = new LoanRequest();
loanRequest1.setId(2);
ibatisTemplate.insert("GoSmarter.loanRequestInsert", loanRequest1);
requestMock.setMethod("GET");
requestMock.setRequestURI("/loanrequests");
handlerAdapter.handle(requestMock, responseMock, loanRequestController);
List loanRequests = mapper.readValue(responseMock.getContentAsString(), List.class);
assertNotNull(loanRequests);
assertEquals(loanRequests.size(), 2);
}

@Test
public void testCreateLoanRequest() throws Exception {
requestMock.setMethod("POST");
String jsonPcUser = mapper.writeValueAsString(loanRequest);
logger.debug(jsonPcUser);
requestMock.setRequestURI("/loanrequests/create/" + jsonPcUser );
handlerAdapter.handle(requestMock, responseMock, loanRequestController);
logger.debug(responseMock.getContentAsString());
assertEquals(responseMock.getContentAsString(), "true");
}

@Test
public void testListLoanUpdate() throws Exception {
requestMock.setMethod("POST");
LoanRequest loanRequest1 = new LoanRequest();
ibatisTemplate.insert("GoSmarter.loanRequestInsert", loanRequest1);
loanRequest1.setCustomerName("krishna prasad");
String jsonPcUser = mapper.writeValueAsString(loanRequest1);
logger.debug(jsonPcUser);
requestMock.setRequestURI("/loanrequests/update/" + jsonPcUser );
handlerAdapter.handle(requestMock, responseMock, loanRequestController);
logger.debug(responseMock.getContentAsString());
assertEquals(responseMock.getContentAsString(), "true");
LoanRequest loanRequest2 = (LoanRequest) ibatisTemplate.queryForObject(
"GoSmarter.loanRequestDetails", 1);
assertEquals(loanRequest2.getCustomerName(), "krishna prasad");
}

@Test
public void testListLoanDelete() throws Exception {
LoanRequest loanRequest1 = new LoanRequest();
ibatisTemplate.insert("GoSmarter.loanRequestInsert", loanRequest1);
requestMock.setMethod("POST");
requestMock.setRequestURI("/loanrequests/delete/1" );
handlerAdapter.handle(requestMock, responseMock, loanRequestController);
List loanRequests = (List) ibatisTemplate
.queryForList("GoSmarter.loanRequestList");
assertEquals(loanRequests.size(), 0);
}

If you see we need to setup the AnnotationMethodHandlerAdapter and setup MappingJacksonHttpMessageConverter. as below,

@Before
public void setUp() {
requestMock = new MockHttpServletRequest();
requestMock.setContentType(MediaType.APPLICATION_JSON_VALUE);
requestMock.setAttribute(HandlerMapping.INTROSPECT_TYPE_LEVEL_MAPPING, Boolean.FALSE);

responseMock = new MockHttpServletResponse();

handlerAdapter = new AnnotationMethodHandlerAdapter();
HttpMessageConverter[] messageConverters = {new MappingJacksonHttpMessageConverter()};
handlerAdapter.setMessageConverters(messageConverters);

mapper = new ObjectMapper();
loanRequest = new LoanRequest();
}

Once we do the setup, we need to add a InitBinder method in the controller as below,

public class LoanRequestController {
@InitBinder
public void initBinder(WebDataBinder b) {
b.registerCustomEditor(LoanRequest.class, new LoanRequestEditor());
}
}

public class LoanRequestEditor extends PropertyEditorSupport {
ObjectMapper mapper = new ObjectMapper();

@Override
public void setAsText(String text) throws IllegalArgumentException {
LoanRequest obj = mapper.readValue(text, LoanRequest.class);
setValue(obj);
}

@Override
public String getAsText() {
return getValue().toString();
}
}

Conclusion

In the above example, we used MockHttpServletRequest and MockHttpServletResponse to do Junit test of REST Services and Spring MVC.

I hope it helped.



Discover how the Watson team is further developing SDKs in Java, Node.js, Python, iOS, and Android to access these services and make programming easy. Brought to you in partnership with IBM.

Topics:

Published at DZone with permission of Krishna Prasad, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}