Created tests for AnnotationHandler class and added a default template
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
package com.raychatter.common.annotation;
|
package com.raychatter.common.annotation;
|
||||||
|
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
@@ -13,45 +15,64 @@ import java.util.Scanner;
|
|||||||
public class AnnotationHandler implements HandlerExceptionResolver {
|
public class AnnotationHandler implements HandlerExceptionResolver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ModelAndView resolveException(final HttpServletRequest request,
|
public ModelAndView resolveException(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final Exception thrownException) {
|
||||||
final HttpServletResponse response,
|
final ExceptionHandler annotation = thrownException.getClass().getAnnotation(ExceptionHandler.class);
|
||||||
final Object handler,
|
|
||||||
final Exception thrownException) {
|
|
||||||
|
|
||||||
final ExceptionHandler exceptionHandlerAnnotation = thrownException.getClass().getAnnotation(ExceptionHandler.class);
|
// This still returns an empty ModelAndView
|
||||||
if (exceptionHandlerAnnotation == null) {
|
if (annotation == null) {
|
||||||
return new ModelAndView();
|
return new ModelAndView();
|
||||||
}
|
}
|
||||||
|
|
||||||
return doStuffWithAnnotation(exceptionHandlerAnnotation, thrownException, response);
|
return doStuffWithAnnotation(annotation, thrownException, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModelAndView doStuffWithAnnotation(final ExceptionHandler exceptionHandlerAnnotation, final Exception thrownException, final HttpServletResponse response) {
|
private ModelAndView doStuffWithAnnotation(final ExceptionHandler exceptionHandlerAnnotation, final Exception thrownException, final HttpServletResponse response) {
|
||||||
|
|
||||||
|
// This is only outside of the try because the null annotation case is handled in resolveException
|
||||||
response.setContentType(exceptionHandlerAnnotation.contentType());
|
response.setContentType(exceptionHandlerAnnotation.contentType());
|
||||||
response.setStatus(exceptionHandlerAnnotation.httpStatus().value());
|
response.setStatus(exceptionHandlerAnnotation.httpStatus().value());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
response.getWriter().write(formatMessage(thrownException));
|
response.getWriter().write(formatMessage(thrownException));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
response.setContentType(MediaType.APPLICATION_XML_VALUE);
|
||||||
|
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||||
|
|
||||||
|
try {
|
||||||
|
response.getWriter().write(formatDefaultMessage(thrownException));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new ModelAndView();
|
return new ModelAndView();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Customize your output message here. If you have multiple dynamic parameters to
|
protected String formatMessage(final Exception thrownException) throws IOException {
|
||||||
// put into your template, you can assign them all in this method.
|
|
||||||
private String formatMessage(final Exception thrownException) {
|
|
||||||
return String.format(readTemplate(), thrownException.getMessage());
|
return String.format(readTemplate(), thrownException.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads the template file until the end of the line
|
protected String formatDefaultMessage(final Exception thrownException) throws IOException {
|
||||||
private String readTemplate() {
|
return String.format(readDefaultTemplate(), thrownException.getMessage());
|
||||||
try {
|
}
|
||||||
|
|
||||||
|
protected String readTemplate() throws IOException {
|
||||||
final InputStream templateFile = new ClassPathResource("error.template").getInputStream();
|
final InputStream templateFile = new ClassPathResource("error.template").getInputStream();
|
||||||
return new Scanner(templateFile, "UTF-8").useDelimiter("\\A").next().trim();
|
return new Scanner(templateFile, "UTF-8").useDelimiter("\\A").next().trim();
|
||||||
} catch (IOException exception) {
|
}
|
||||||
return "Default Error Message: %s";
|
|
||||||
|
// Extract into a new protected method to grab input stream; spy that new method, returning null?
|
||||||
|
protected String readDefaultTemplate() {
|
||||||
|
try {
|
||||||
|
final InputStream templateFile = getInputStream("defaults/default.template");
|
||||||
|
return new Scanner(templateFile, "UTF-8").useDelimiter("\\A").next().trim();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
return "Error: %s";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected InputStream getInputStream(String filepath) throws IOException {
|
||||||
|
return new ClassPathResource(filepath).getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<error>
|
||||||
|
%s
|
||||||
|
</error>
|
||||||
@@ -1,13 +1,52 @@
|
|||||||
package com.raychatter.common.annotation;
|
package com.raychatter.common.annotation;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class AnnotationHandlerTest extends TestCase {
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.doThrow;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
|
||||||
|
public class AnnotationHandlerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldReturnModelAndViewIfAnnotationIsNull() {
|
public void formatMessage_ShouldRenderUserTemplate_WhenUserTemplateGiven() throws Exception {
|
||||||
AnnotationHandler annotationHandler = new AnnotationHandler();
|
final String givenUserTemplate = "A TEMPLATE: %s";
|
||||||
|
final String exceptionMessage = "AN ERROR MESSAGE";
|
||||||
|
final String expectedResult = "A TEMPLATE: AN ERROR MESSAGE";
|
||||||
|
|
||||||
|
AnnotationHandler sut = spy(new AnnotationHandler());
|
||||||
|
doReturn(givenUserTemplate).when(sut).readTemplate();
|
||||||
|
|
||||||
|
final String actual = sut.formatMessage(new Exception(exceptionMessage));
|
||||||
|
|
||||||
|
Assert.assertEquals(expectedResult, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test public void formatDefaultMessage_ShouldRenderDefaultUserTemplate_WhenNoUserTemplateGiven() throws Exception {
|
||||||
|
final String defaultTemplate = "DEFAULT TEMPLATE: %s";
|
||||||
|
final String exceptionMessage = "AN ERROR MESSAGE";
|
||||||
|
final String expectedMessage = "DEFAULT TEMPLATE: AN ERROR MESSAGE";
|
||||||
|
|
||||||
|
AnnotationHandler spyAnnotationHandler = spy(new AnnotationHandler());
|
||||||
|
doReturn(defaultTemplate).when(spyAnnotationHandler).readDefaultTemplate();
|
||||||
|
|
||||||
|
final String actual = spyAnnotationHandler.formatDefaultMessage(new Exception(exceptionMessage));
|
||||||
|
|
||||||
|
Assert.assertEquals(expectedMessage, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test public void readDefaultTemplate_ShouldCatchIOException_WhenDefaultTemplateNotFound() throws Exception {
|
||||||
|
final String expectedTemplate = "Error: %s";
|
||||||
|
final String defaultFilepath = "defaults/default.template";
|
||||||
|
|
||||||
|
AnnotationHandler spyAnnotationHandler = spy(new AnnotationHandler());
|
||||||
|
doThrow(new IOException()).when(spyAnnotationHandler).getInputStream(defaultFilepath);
|
||||||
|
|
||||||
|
final String actualTemplate = spyAnnotationHandler.readDefaultTemplate();
|
||||||
|
|
||||||
|
Assert.assertEquals(expectedTemplate, actualTemplate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user