Browse Source

Avoid ClassCastException in HandlerResultMatchers.methodCall()

pull/1073/merge
Sam Brannen 10 years ago
parent
commit
eaa9511921
  1. 33
      spring-test/src/main/java/org/springframework/test/web/servlet/result/HandlerResultMatchers.java
  2. 14
      spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/HandlerAssertionTests.java

33
spring-test/src/main/java/org/springframework/test/web/servlet/result/HandlerResultMatchers.java

@ -25,12 +25,14 @@ import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder.MethodInvocationInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.springframework.test.util.AssertionErrors.assertEquals; import static org.springframework.test.util.AssertionErrors.assertEquals;
import static org.springframework.test.util.AssertionErrors.assertTrue; import static org.springframework.test.util.AssertionErrors.assertTrue;
import static org.springframework.test.util.AssertionErrors.fail;
/** /**
* Factory for assertions on the selected handler or handler method. * Factory for assertions on the selected handler or handler method.
@ -43,6 +45,7 @@ import static org.springframework.test.util.AssertionErrors.assertTrue;
* which is used by default with the Spring MVC Java config and XML namespace. * which is used by default with the Spring MVC Java config and XML namespace.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @author Sam Brannen
* @since 3.2 * @since 3.2
*/ */
public class HandlerResultMatchers { public class HandlerResultMatchers {
@ -75,13 +78,13 @@ public class HandlerResultMatchers {
} }
/** /**
* Assert the controller method used to process the request. The expected * Assert the controller method used to process the request.
* method is specified through a "mock" controller method invocation * <p>The expected method is specified through a "mock" controller method
* similar to {@link MvcUriComponentsBuilder#fromMethodCall(Object)}. * invocation similar to {@link MvcUriComponentsBuilder#fromMethodCall(Object)}.
* <p>For example given this controller: * <p>For example, given this controller:
* <pre class="code"> * <pre class="code">
* &#064;RestController * &#064;RestController
* static class SimpleController { * public class SimpleController {
* *
* &#064;RequestMapping("/") * &#064;RequestMapping("/")
* public ResponseEntity<Void> handle() { * public ResponseEntity<Void> handle() {
@ -89,19 +92,29 @@ public class HandlerResultMatchers {
* } * }
* } * }
* </pre> * </pre>
* <p>A test can be performed: * <p>A test that has statically imported {@link MvcUriComponentsBuilder#on}
* can be performed as follows:
* <pre class="code"> * <pre class="code">
* mockMvc.perform(get("/")) * mockMvc.perform(get("/"))
* .andExpect(handler().methodCall(on(SimpleController.class).handle())); * .andExpect(handler().methodCall(on(SimpleController.class).handle()));
* </pre> * </pre>
*
* @param obj either the value returned from a "mock" controller invocation
* or the "mock" controller itself after an invocation
*/ */
public ResultMatcher methodCall(final Object info) { public ResultMatcher methodCall(final Object obj) {
return new ResultMatcher() { return new ResultMatcher() {
@Override @Override
public void match(MvcResult result) throws Exception { public void match(MvcResult result) throws Exception {
HandlerMethod handlerMethod = getHandlerMethod(result); if (!MethodInvocationInfo.class.isInstance(obj)) {
Method method = ((MvcUriComponentsBuilder.MethodInvocationInfo) info).getControllerMethod(); fail(String.format("The supplied object [%s] is not an instance of %s. "
assertEquals("HandlerMethod", method, handlerMethod.getMethod()); + "Ensure that you invoke the handler method via MvcUriComponentsBuilder.on().",
obj, MethodInvocationInfo.class.getName()));
}
MethodInvocationInfo invocationInfo = (MethodInvocationInfo) obj;
Method expected = invocationInfo.getControllerMethod();
Method actual = getHandlerMethod(result).getMethod();
assertEquals("Handler method", expected, actual);
} }
}; };
} }

14
spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/HandlerAssertionTests.java

@ -18,7 +18,9 @@ package org.springframework.test.web.servlet.samples.standalone.resultmatchers;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MockMvc;
@ -39,11 +41,14 @@ import static org.springframework.web.servlet.mvc.method.annotation.MvcUriCompon
* Examples of expectations on the controller type and controller method. * Examples of expectations on the controller type and controller method.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @author Sam Brannen
*/ */
public class HandlerAssertionTests { public class HandlerAssertionTests {
private final MockMvc mockMvc = standaloneSetup(new SimpleController()).alwaysExpect(status().isOk()).build(); private final MockMvc mockMvc = standaloneSetup(new SimpleController()).alwaysExpect(status().isOk()).build();
@Rule
public final ExpectedException exception = ExpectedException.none();
@Test @Test
@ -52,6 +57,15 @@ public class HandlerAssertionTests {
} }
@Test @Test
public void methodCallOnNonMock() throws Exception {
exception.expect(AssertionError.class);
exception.expectMessage("The supplied object [bogus] is not an instance of");
exception.expectMessage(MvcUriComponentsBuilder.MethodInvocationInfo.class.getName());
exception.expectMessage("Ensure that you invoke the handler method via MvcUriComponentsBuilder.on()");
this.mockMvc.perform(get("/")).andExpect(handler().methodCall("bogus"));
}
@Test @Test
public void methodCall() throws Exception { public void methodCall() throws Exception {
this.mockMvc.perform(get("/")).andExpect(handler().methodCall(on(SimpleController.class).handle())); this.mockMvc.perform(get("/")).andExpect(handler().methodCall(on(SimpleController.class).handle()));

Loading…
Cancel
Save