Created tests for AnnotationHandler class and added a default template

This commit is contained in:
Rachel Walker
2012-11-29 15:23:11 -08:00
parent c5bbd4942b
commit a354618021
3 changed files with 86 additions and 22 deletions

View File

@@ -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();
}
} }

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<error>
%s
</error>

View File

@@ -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);
}
} }