diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/HeaderResultMatchers.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/HeaderResultMatchers.java index 6e53496fa2cd870eb955dcf7b7b9752411f9150f..ee470016d7ee3b20ba95731984d5792103a8ce85 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/HeaderResultMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/HeaderResultMatchers.java @@ -16,19 +16,22 @@ package org.springframework.test.web.servlet.result; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + import org.hamcrest.Matcher; 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.*; -import static org.springframework.test.util.AssertionErrors.*; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.springframework.test.util.AssertionErrors.assertEquals; +import static org.springframework.test.util.AssertionErrors.assertTrue; /** * Factory for response header assertions. @@ -52,8 +55,8 @@ public class HeaderResultMatchers { /** - * Assert the primary value of the named response header with the given - * Hamcrest {@link Matcher}. + * Assert the primary value of the response header with the given Hamcrest + * String {@code Matcher}. */ public ResultMatcher string(final String name, final Matcher matcher) { return new ResultMatcher() { @@ -65,13 +68,42 @@ public class HeaderResultMatchers { } /** - * Assert the primary value of the named response header as a {@link String}. + * Assert the values of the response header with the given Hamcrest + * Iterable {@link Matcher}. + * @since 4.3 + */ + public ResultMatcher stringValues(final String name, final Matcher> matcher) { + return new ResultMatcher() { + @Override + public void match(MvcResult result) { + List values = result.getResponse().getHeaders(name); + assertThat("Response header " + name, values, matcher); + } + }; + } + + /** + * Assert the primary value of the response header as a String value. */ public ResultMatcher string(final String name, final String value) { return new ResultMatcher() { @Override public void match(MvcResult result) { - assertEquals("Response header " + name, value, result.getResponse().getHeader(name)); + assertEquals("Response header " + name, result.getResponse().getHeader(name), value); + } + }; + } + + /** + * Assert the values of the response header as String values. + * @since 4.3 + */ + public ResultMatcher stringValues(final String name, final String... values) { + return new ResultMatcher() { + @Override + public void match(MvcResult result) { + List actual = result.getResponse().getHeaderValues(name); + assertEquals("Response header " + name, Arrays.asList(values), actual); } }; } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/HeaderAssertionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/HeaderAssertionTests.java index d9160d8fee6fb3b46f5aa6fb4ba195d7f1b87293..1bd62965a5e943ad3dcaa1d033d5bf13fa2b8fed 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/HeaderAssertionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/standalone/resultmatchers/HeaderAssertionTests.java @@ -33,13 +33,17 @@ 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; @@ -95,6 +99,18 @@ public class HeaderAssertionTests { .andExpect(header().string(LAST_MODIFIED, equalTo(now))); } + @Test + public void multiStringHeaderValue() throws Exception { + this.mockMvc.perform(get("/persons/1")).andExpect(header().stringValues(VARY, "foo", "bar")); + } + + @SuppressWarnings("unchecked") + @Test + public void multiStringHeaderValueWithMatchers() throws Exception { + this.mockMvc.perform(get("/persons/1")) + .andExpect(header().stringValues(VARY, hasItems(containsString("foo"), startsWith("bar")))); + } + @Test public void dateValueWithCorrectResponseHeaderValue() throws Exception { this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, minuteAgo)) @@ -111,7 +127,7 @@ public class HeaderAssertionTests { public void stringWithMissingResponseHeader() throws Exception { this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, now)) .andExpect(status().isNotModified()) - .andExpect(header().string("X-Custom-Header", (String) null)); + .andExpect(header().stringValues("X-Custom-Header")); } @Test diff --git a/src/asciidoc/whats-new.adoc b/src/asciidoc/whats-new.adoc index 09c03a32460aaa394cfb2875d20848a8187ebdb0..003adb49c20e6ce5713b59380e251a09ae28c97d 100644 --- a/src/asciidoc/whats-new.adoc +++ b/src/asciidoc/whats-new.adoc @@ -672,3 +672,4 @@ Spring 4.3 also improves the caching abstraction as follows: === Testing Improvements * The JUnit support in the _Spring TestContext Framework_ now requires JUnit 4.12 or higher. +* HeaderResultMatchers in Spring MVC Test supports expectations on multiple header values \ No newline at end of file