Correct attributeHasNoErrors message in ModelResultMatchers

Includes consistent name quoting.

Issue: SPR-15487
(cherry picked from commit 0479dc9)
This commit is contained in:
Juergen Hoeller 2017-04-26 21:32:50 +02:00
parent 554c3f3d7e
commit 38089d8e66
11 changed files with 76 additions and 97 deletions

View File

@ -35,6 +35,7 @@ import static org.springframework.test.util.AssertionErrors.*;
/**
* Factory for response content assertions.
*
* <p>An instance of this class is typically accessed via
* {@link MockMvcResultMatchers#content}.
*
@ -217,7 +218,6 @@ public class ContentResultMatchers {
* are "similar" - i.e. they contain the same attribute-value pairs
* regardless of formatting with a lenient checking (extensible, and non-strict array
* ordering).
*
* @param jsonContent the expected JSON content
* @since 4.1
*/
@ -226,19 +226,15 @@ public class ContentResultMatchers {
}
/**
* Parse the response content and the given string as JSON and assert the two
* are "similar" - i.e. they contain the same attribute-value pairs
* regardless of formatting.
*
* Parse the response content and the given string as JSON and assert the two are "similar" -
* i.e. they contain the same attribute-value pairs regardless of formatting.
* <p>Can compare in two modes, depending on {@code strict} parameter value:
* <ul>
* <li>{@code true}: strict checking. Not extensible, and strict array ordering.</li>
* <li>{@code false}: lenient checking. Extensible, and non-strict array ordering.</li>
* <li>{@code true}: strict checking. Not extensible, and strict array ordering.</li>
* <li>{@code false}: lenient checking. Extensible, and non-strict array ordering.</li>
* </ul>
*
* <p>Use of this matcher requires the <a
* href="http://jsonassert.skyscreamer.org/">JSONassert<a/> library.
*
* @param jsonContent the expected JSON content
* @param strict enables strict checking
* @since 4.2

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,6 +26,7 @@ import static org.springframework.test.util.AssertionErrors.*;
/**
* Factory for "output" flash attribute assertions.
*
* <p>An instance of this class is typically accessed via
* {@link MockMvcResultMatchers#flash}.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,13 +29,12 @@ import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBui
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;
import static org.hamcrest.MatcherAssert.*;
import static org.springframework.test.util.AssertionErrors.*;
/**
* Factory for assertions on the selected handler or handler method.
*
* <p>An instance of this class is typically accessed via
* {@link MockMvcResultMatchers#handler}.
*
@ -50,7 +49,6 @@ import static org.springframework.test.util.AssertionErrors.fail;
*/
public class HandlerResultMatchers {
/**
* Protected constructor.
* Use {@link MockMvcResultMatchers#handler()}.
@ -67,7 +65,7 @@ public class HandlerResultMatchers {
@Override
public void match(MvcResult result) throws Exception {
Object handler = result.getHandler();
assertTrue("No handler: ", handler != null);
assertTrue("No handler", handler != null);
Class<?> actual = handler.getClass();
if (HandlerMethod.class.isInstance(handler)) {
actual = ((HandlerMethod) handler).getBeanType();
@ -98,7 +96,6 @@ public class HandlerResultMatchers {
* mockMvc.perform(get("/"))
* .andExpect(handler().methodCall(on(SimpleController.class).handle()));
* </pre>
*
* @param obj either the value returned from a "mock" controller invocation
* or the "mock" controller itself after an invocation
*/
@ -106,9 +103,9 @@ public class HandlerResultMatchers {
return new ResultMatcher() {
@Override
public void match(MvcResult result) throws Exception {
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().",
if (!(obj instanceof MethodInvocationInfo)) {
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;
@ -159,6 +156,7 @@ public class HandlerResultMatchers {
};
}
private static HandlerMethod getHandlerMethod(MvcResult result) {
Object handler = result.getHandler();
assertTrue("No handler: ", handler != null);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,12 +29,12 @@ import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultMatcher;
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.hamcrest.MatcherAssert.*;
import static org.springframework.test.util.AssertionErrors.*;
/**
* Factory for response header assertions.
*
* <p>An instance of this class is available via
* {@link MockMvcResultMatchers#header}.
*
@ -45,7 +45,6 @@ import static org.springframework.test.util.AssertionErrors.assertTrue;
*/
public class HeaderResultMatchers {
/**
* Protected constructor.
* See {@link MockMvcResultMatchers#header()}.
@ -62,7 +61,7 @@ public class HeaderResultMatchers {
return new ResultMatcher() {
@Override
public void match(MvcResult result) {
assertThat("Response header " + name, result.getResponse().getHeader(name), matcher);
assertThat("Response header '" + name + "'", result.getResponse().getHeader(name), matcher);
}
};
}
@ -77,7 +76,7 @@ public class HeaderResultMatchers {
@Override
public void match(MvcResult result) {
List<String> values = result.getResponse().getHeaders(name);
assertThat("Response header " + name, values, matcher);
assertThat("Response header '" + name + "'", values, matcher);
}
};
}
@ -89,7 +88,7 @@ public class HeaderResultMatchers {
return new ResultMatcher() {
@Override
public void match(MvcResult result) {
assertEquals("Response header " + name, value, result.getResponse().getHeader(name));
assertEquals("Response header '" + name + "'", value, result.getResponse().getHeader(name));
}
};
}
@ -103,7 +102,7 @@ public class HeaderResultMatchers {
@Override
public void match(MvcResult result) {
List<Object> actual = result.getResponse().getHeaderValues(name);
assertEquals("Response header " + name, Arrays.asList(values), actual);
assertEquals("Response header '" + name + "'", Arrays.asList(values), actual);
}
};
}
@ -116,7 +115,7 @@ public class HeaderResultMatchers {
return new ResultMatcher() {
@Override
public void match(MvcResult result) {
assertTrue("Response should not contain header " + name,
assertTrue("Response should not contain header '" + name + "'",
!result.getResponse().containsHeader(name));
}
};
@ -133,8 +132,8 @@ public class HeaderResultMatchers {
@Override
public void match(MvcResult result) {
MockHttpServletResponse response = result.getResponse();
assertTrue("Response does not contain header " + name, response.containsHeader(name));
assertEquals("Response header " + name, value, Long.parseLong(response.getHeader(name)));
assertTrue("Response does not contain header '" + name + "'", response.containsHeader(name));
assertEquals("Response header '" + name + "'", value, Long.parseLong(response.getHeader(name)));
}
};
}
@ -156,8 +155,8 @@ public class HeaderResultMatchers {
format.setTimeZone(TimeZone.getTimeZone("GMT"));
String formatted = format.format(new Date(value));
MockHttpServletResponse response = result.getResponse();
assertTrue("Response does not contain header " + name, response.containsHeader(name));
assertEquals("Response header " + name, formatted, response.getHeader(name));
assertTrue("Response does not contain header '" + name + "'", response.containsHeader(name));
assertEquals("Response header '" + name + "'", formatted, response.getHeader(name));
}
};
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -31,6 +31,7 @@ import org.springframework.util.StringUtils;
/**
* Factory for assertions on the response content using
* <a href="https://github.com/jayway/JsonPath">JsonPath</a> expressions.
*
* <p>An instance of this class is typically accessed via
* {@link MockMvcResultMatchers#jsonPath(String, Matcher)} or
* {@link MockMvcResultMatchers#jsonPath(String, Object...)}.
@ -258,9 +259,8 @@ public class JsonPathResultMatchers {
MatcherAssert.assertThat(reason, content, StringStartsWith.startsWith(this.prefix));
return content.substring(this.prefix.length());
}
catch (StringIndexOutOfBoundsException oobe) {
throw new AssertionError(
"JSON prefix \"" + this.prefix + "\" not found, exception: " + oobe.getMessage());
catch (StringIndexOutOfBoundsException ex) {
throw new AssertionError("JSON prefix \"" + this.prefix + "\" not found", ex);
}
}
else {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -30,6 +30,7 @@ import static org.springframework.test.util.AssertionErrors.*;
/**
* Factory for assertions on the model.
*
* <p>An instance of this class is typically accessed via
* {@link MockMvcResultMatchers#model}.
*
@ -108,11 +109,10 @@ public class ModelResultMatchers {
*/
public ResultMatcher attributeErrorCount(final String name, final int expectedCount) {
return new ResultMatcher() {
@Override
public void match(MvcResult result) throws Exception {
ModelAndView mav = getModelAndView(result);
Errors errors = getBindingResult(mav, name);
assertEquals("Binding/validation error count for attribute [" + name + "], ",
assertEquals("Binding/validation error count for attribute '" + name + "', ",
expectedCount, errors.getErrorCount());
}
};
@ -123,12 +123,11 @@ public class ModelResultMatchers {
*/
public ResultMatcher attributeHasErrors(final String... names) {
return new ResultMatcher() {
@Override
public void match(MvcResult mvcResult) throws Exception {
ModelAndView mav = getModelAndView(mvcResult);
for (String name : names) {
BindingResult result = getBindingResult(mav, name);
assertTrue("No errors for attribute [" + name + "]", result.hasErrors());
assertTrue("No errors for attribute '" + name + "'", result.hasErrors());
}
}
};
@ -139,12 +138,12 @@ public class ModelResultMatchers {
*/
public ResultMatcher attributeHasNoErrors(final String... names) {
return new ResultMatcher() {
@Override
public void match(MvcResult mvcResult) throws Exception {
ModelAndView mav = getModelAndView(mvcResult);
for (String name : names) {
BindingResult result = getBindingResult(mav, name);
assertTrue("No errors for attribute [" + name + "]", !result.hasErrors());
assertTrue("Unexpected errors for attribute '" + name + "': " + result.getAllErrors(),
!result.hasErrors());
}
}
};
@ -155,14 +154,13 @@ public class ModelResultMatchers {
*/
public ResultMatcher attributeHasFieldErrors(final String name, final String... fieldNames) {
return new ResultMatcher() {
@Override
public void match(MvcResult mvcResult) throws Exception {
ModelAndView mav = getModelAndView(mvcResult);
BindingResult result = getBindingResult(mav, name);
assertTrue("No errors for attribute: [" + name + "]", result.hasErrors());
assertTrue("No errors for attribute '" + name + "'", result.hasErrors());
for (final String fieldName : fieldNames) {
boolean hasFieldErrors = result.hasFieldErrors(fieldName);
assertTrue("No errors for field: [" + fieldName + "] of attribute [" + name + "]", hasFieldErrors);
assertTrue("No errors for field '" + fieldName + "' of attribute '" + name + "'", hasFieldErrors);
}
}
};
@ -177,11 +175,9 @@ public class ModelResultMatchers {
public void match(MvcResult mvcResult) throws Exception {
ModelAndView mav = getModelAndView(mvcResult);
BindingResult result = getBindingResult(mav, name);
assertTrue("No errors for attribute: [" + name + "]", result.hasErrors());
assertTrue("No errors for attribute '" + name + "'", result.hasErrors());
boolean hasFieldErrors = result.hasFieldErrors(fieldName);
assertTrue("No errors for field: [" + fieldName + "] of attribute [" + name + "]", hasFieldErrors);
assertTrue("No errors for field '" + fieldName + "' of attribute '" + name + "'", hasFieldErrors);
String code = result.getFieldError(fieldName).getCode();
assertTrue("Expected error code '" + error + "' but got '" + code + "'", code.equals(error));
}
@ -201,10 +197,8 @@ public class ModelResultMatchers {
ModelAndView mav = getModelAndView(mvcResult);
BindingResult result = getBindingResult(mav, name);
assertTrue("No errors for attribute: [" + name + "]", result.hasErrors());
boolean hasFieldErrors = result.hasFieldErrors(fieldName);
assertTrue("No errors for field: [" + fieldName + "] of attribute [" + name + "]", hasFieldErrors);
assertTrue("No errors for field '" + fieldName + "' of attribute '" + name + "'", hasFieldErrors);
String code = result.getFieldError(fieldName).getCode();
assertThat("Field name '" + fieldName + "' of attribute '" + name + "'", code, matcher);
}
@ -247,8 +241,7 @@ public class ModelResultMatchers {
ModelAndView mav = getModelAndView(result);
for (Object value : mav.getModel().values()) {
if (value instanceof Errors) {
assertTrue("Unexpected binding/validation error(s) [" + value + "]",
!((Errors) value).hasErrors());
assertTrue("Unexpected binding/validation errors: " + value, !((Errors) value).hasErrors());
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -32,6 +32,7 @@ import static org.springframework.test.util.AssertionErrors.*;
/**
* Factory for assertions on the request.
*
* <p>An instance of this class is typically accessed via
* {@link MockMvcResultMatchers#request}.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,6 +27,7 @@ import static org.springframework.test.util.AssertionErrors.*;
/**
* Factory for assertions on the response status.
*
* <p>An instance of this class is typically accessed via
* {@link MockMvcResultMatchers#status}.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,6 +27,7 @@ import static org.springframework.test.util.AssertionErrors.*;
/**
* Factory for assertions on the selected view.
*
* <p>An instance of this class is typically accessed via
* {@link MockMvcResultMatchers#view}.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,6 +29,7 @@ import org.springframework.test.web.servlet.ResultMatcher;
/**
* Factory for assertions on the response content using XPath expressions.
*
* <p>An instance of this class is typically accessed via
* {@link MockMvcResultMatchers#xpath}.
*
@ -55,6 +56,7 @@ public class XpathResultMatchers {
this.xpathHelper = new XpathExpectationsHelper(expression, namespaces, args);
}
/**
* Evaluate the XPath and assert the {@link Node} content found with the
* given Hamcrest {@link Matcher}.
@ -196,4 +198,4 @@ public class XpathResultMatchers {
};
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -33,22 +33,12 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.WebRequest;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.springframework.http.HttpHeaders.IF_MODIFIED_SINCE;
import static org.springframework.http.HttpHeaders.LAST_MODIFIED;
import static org.springframework.http.HttpHeaders.VARY;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import static org.springframework.http.HttpHeaders.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;
/**
* Examples of expectations on response header values.
@ -146,24 +136,20 @@ public class HeaderAssertionTests {
fail(ERROR_MESSAGE);
}
catch (AssertionError e) {
if (ERROR_MESSAGE.equals(e.getMessage())) {
throw e;
catch (AssertionError err) {
if (ERROR_MESSAGE.equals(err.getMessage())) {
throw err;
}
assertEquals("Response does not contain header " + "X-Custom-Header", e.getMessage());
assertEquals("Response does not contain header 'X-Custom-Header'", err.getMessage());
}
}
// SPR-10771
@Test
@Test // SPR-10771
public void doesNotExist() throws Exception {
this.mockMvc.perform(get("/persons/1")).andExpect(header().doesNotExist("X-Custom-Header"));
}
// SPR-10771
@Test(expected = AssertionError.class)
@Test(expected = AssertionError.class) // SPR-10771
public void doesNotExistFail() throws Exception {
this.mockMvc.perform(get("/persons/1")).andExpect(header().doesNotExist(LAST_MODIFIED));
}
@ -189,6 +175,7 @@ public class HeaderAssertionTests {
this.mockMvc.perform(get("/persons/1")).andExpect(header().longValue("X-Rate-Limiting", 1));
}
private void assertIncorrectResponseHeader(ResultMatcher matcher, String unexpected) throws Exception {
try {
this.mockMvc.perform(get("/persons/1")
@ -197,15 +184,15 @@ public class HeaderAssertionTests {
fail(ERROR_MESSAGE);
}
catch (AssertionError e) {
if (ERROR_MESSAGE.equals(e.getMessage())) {
throw e;
catch (AssertionError err) {
if (ERROR_MESSAGE.equals(err.getMessage())) {
throw err;
}
// SPR-10659: ensure header name is in the message
// Unfortunately, we can't control formatting from JUnit or Hamcrest.
assertMessageContains(e, "Response header " + LAST_MODIFIED);
assertMessageContains(e, unexpected);
assertMessageContains(e, now);
assertMessageContains(err, "Response header '" + LAST_MODIFIED + "'");
assertMessageContains(err, unexpected);
assertMessageContains(err, now);
}
}
@ -220,7 +207,6 @@ public class HeaderAssertionTests {
private long timestamp;
public void setStubTimestamp(long timestamp) {
this.timestamp = timestamp;
}
@ -239,4 +225,5 @@ public class HeaderAssertionTests {
return this.timestamp;
}
}
}