diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/HandlerResultMatchers.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/HandlerResultMatchers.java index 591eeb8cb20..cc55e188072 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/HandlerResultMatchers.java +++ b/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.web.method.HandlerMethod; 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.RequestMappingHandlerMapping; import static org.hamcrest.MatcherAssert.assertThat; import static org.springframework.test.util.AssertionErrors.assertEquals; 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. @@ -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. * * @author Rossen Stoyanchev + * @author Sam Brannen * @since 3.2 */ public class HandlerResultMatchers { @@ -75,13 +78,13 @@ public class HandlerResultMatchers { } /** - * Assert the controller method used to process the request. The expected - * method is specified through a "mock" controller method invocation - * similar to {@link MvcUriComponentsBuilder#fromMethodCall(Object)}. - *
For example given this controller: + * Assert the controller method used to process the request. + *
The expected method is specified through a "mock" controller method + * invocation similar to {@link MvcUriComponentsBuilder#fromMethodCall(Object)}. + *
For example, given this controller: *
* @RestController
- * static class SimpleController {
+ * public class SimpleController {
*
* @RequestMapping("/")
* public ResponseEntity handle() {
@@ -89,19 +92,29 @@ public class HandlerResultMatchers {
* }
* }
*
- * A test can be performed: + *
A test that has statically imported {@link MvcUriComponentsBuilder#on} + * can be performed as follows: *
* mockMvc.perform(get("/"))
* .andExpect(handler().methodCall(on(SimpleController.class).handle()));
*
+ *
+ * @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() {
@Override
public void match(MvcResult result) throws Exception {
- HandlerMethod handlerMethod = getHandlerMethod(result);
- Method method = ((MvcUriComponentsBuilder.MethodInvocationInfo) info).getControllerMethod();
- assertEquals("HandlerMethod", method, handlerMethod.getMethod());
+ if (!MethodInvocationInfo.class.isInstance(obj)) {
+ fail(String.format("The supplied object [%s] is not an instance of %s. "
+ + "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);
}
};
}
diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/HandlerAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/HandlerAssertionTests.java
index a17e7c02b96..2c671bbf655 100644
--- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/HandlerAssertionTests.java
+++ b/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 org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.springframework.http.ResponseEntity;
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.
*
* @author Rossen Stoyanchev
+ * @author Sam Brannen
*/
public class HandlerAssertionTests {
private final MockMvc mockMvc = standaloneSetup(new SimpleController()).alwaysExpect(status().isOk()).build();
+ @Rule
+ public final ExpectedException exception = ExpectedException.none();
@Test
@@ -52,6 +57,15 @@ public class HandlerAssertionTests {
}
@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
public void methodCall() throws Exception {
this.mockMvc.perform(get("/")).andExpect(handler().methodCall(on(SimpleController.class).handle()));