Polish HeaderResultMatchers
This commit is contained in:
parent
18db77da7c
commit
ae224bed3e
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.test.web.servlet.result;
|
|||
|
||||
import org.hamcrest.Matcher;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
import org.springframework.test.web.servlet.ResultMatcher;
|
||||
|
||||
|
@ -31,7 +32,7 @@ import java.util.TimeZone;
|
|||
|
||||
/**
|
||||
* Factory for response header assertions.
|
||||
* <p>An instance of this class is usually accessed via
|
||||
* <p>An instance of this class is available via
|
||||
* {@link MockMvcResultMatchers#header}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
|
@ -41,13 +42,15 @@ import java.util.TimeZone;
|
|||
*/
|
||||
public class HeaderResultMatchers {
|
||||
|
||||
|
||||
/**
|
||||
* Protected constructor.
|
||||
* Use {@link MockMvcResultMatchers#header()}.
|
||||
* See {@link MockMvcResultMatchers#header()}.
|
||||
*/
|
||||
protected HeaderResultMatchers() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Assert the primary value of the named response header with the given
|
||||
* Hamcrest {@link Matcher}.
|
||||
|
@ -81,23 +84,25 @@ public class HeaderResultMatchers {
|
|||
return new ResultMatcher() {
|
||||
@Override
|
||||
public void match(MvcResult result) {
|
||||
assertTrue("Response should not contain header " + name, !result.getResponse().containsHeader(name));
|
||||
assertTrue("Response should not contain header " + name,
|
||||
!result.getResponse().containsHeader(name));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the primary value of the named response header as a {@code long}.
|
||||
* <p>The {@link ResultMatcher} returned by this method throws an {@link AssertionError}
|
||||
* if the response does not contain the specified header, or if the supplied
|
||||
* {@code value} does not match the primary value.
|
||||
* <p>The {@link ResultMatcher} returned by this method throws an
|
||||
* {@link AssertionError} if the response does not contain the specified
|
||||
* header, or if the supplied {@code value} does not match the primary value.
|
||||
*/
|
||||
public ResultMatcher longValue(final String name, final long value) {
|
||||
return new ResultMatcher() {
|
||||
@Override
|
||||
public void match(MvcResult result) {
|
||||
assertTrue("Response does not contain header " + name, result.getResponse().containsHeader(name));
|
||||
assertEquals("Response header " + name, value, Long.parseLong(result.getResponse().getHeader(name)));
|
||||
MockHttpServletResponse response = result.getResponse();
|
||||
assertTrue("Response does not contain header " + name, response.containsHeader(name));
|
||||
assertEquals("Response header " + name, value, Long.parseLong(response.getHeader(name)));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -105,10 +110,9 @@ public class HeaderResultMatchers {
|
|||
/**
|
||||
* Assert the primary value of the named response header as a date String,
|
||||
* using the preferred date format described in RFC 7231.
|
||||
* <p>The {@link ResultMatcher} returned by this method throws an {@link AssertionError}
|
||||
* if the response does not contain the specified header, or if the supplied
|
||||
* {@code value} does not match the primary value.
|
||||
*
|
||||
* <p>The {@link ResultMatcher} returned by this method throws an
|
||||
* {@link AssertionError} if the response does not contain the specified
|
||||
* header, or if the supplied {@code value} does not match the primary value.
|
||||
* @see <a href="https://tools.ietf.org/html/rfc7231#section-7.1.1.1">Section 7.1.1.1 of RFC 7231</a>
|
||||
* @since 4.2
|
||||
*/
|
||||
|
@ -118,8 +122,10 @@ public class HeaderResultMatchers {
|
|||
public void match(MvcResult result) {
|
||||
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
|
||||
format.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
assertTrue("Response does not contain header " + name, result.getResponse().containsHeader(name));
|
||||
assertEquals("Response header " + name, format.format(new Date(value)), result.getResponse().getHeader(name));
|
||||
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));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
|
@ -16,6 +16,11 @@
|
|||
|
||||
package org.springframework.test.web.servlet.samples.standalone.resultmatchers;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -28,16 +33,18 @@ 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.*;
|
||||
import static org.junit.Assert.*;
|
||||
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.*;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
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.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 java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Examples of expectations on response header values.
|
||||
|
@ -48,86 +55,83 @@ import java.util.TimeZone;
|
|||
*/
|
||||
public class HeaderAssertionTests {
|
||||
|
||||
private static final String EXPECTED_ASSERTION_ERROR_MSG = "Should have thrown an AssertionError";
|
||||
private static final String ERROR_MESSAGE = "Should have thrown an AssertionError";
|
||||
|
||||
private static final String IF_MODIFIED_SINCE = "If-Modified-Since";
|
||||
|
||||
private static final String LAST_MODIFIED = "Last-Modified";
|
||||
|
||||
private final long currentTime = System.currentTimeMillis();
|
||||
|
||||
private String now;
|
||||
|
||||
private String oneMinuteAgo;
|
||||
private String minuteAgo;
|
||||
|
||||
private String oneSecondLater;
|
||||
private String secondLater;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
private PersonController personController;
|
||||
private final long currentTime = System.currentTimeMillis();
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
|
||||
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
this.now = dateFormat.format(new Date(currentTime));
|
||||
this.oneMinuteAgo = dateFormat.format(new Date(currentTime - (1000 * 60)));
|
||||
this.oneSecondLater = dateFormat.format(new Date(currentTime + 1000));
|
||||
this.personController = new PersonController();
|
||||
this.personController.setStubTimestamp(currentTime);
|
||||
this.mockMvc = standaloneSetup(this.personController).build();
|
||||
this.now = dateFormat.format(new Date(this.currentTime));
|
||||
this.minuteAgo = dateFormat.format(new Date(this.currentTime - (1000 * 60)));
|
||||
this.secondLater = dateFormat.format(new Date(this.currentTime + 1000));
|
||||
|
||||
PersonController controller = new PersonController();
|
||||
controller.setStubTimestamp(this.currentTime);
|
||||
this.mockMvc = standaloneSetup(controller).build();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void stringWithCorrectResponseHeaderValue() throws Exception {
|
||||
this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, oneMinuteAgo))//
|
||||
.andExpect(header().string(LAST_MODIFIED, now));
|
||||
this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, minuteAgo))
|
||||
.andExpect(header().string(LAST_MODIFIED, now));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stringWithMatcherAndCorrectResponseHeaderValue() throws Exception {
|
||||
this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, oneMinuteAgo))//
|
||||
.andExpect(header().string(LAST_MODIFIED, equalTo(now)));
|
||||
this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, minuteAgo))
|
||||
.andExpect(header().string(LAST_MODIFIED, equalTo(now)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dateValueWithCorrectResponseHeaderValue() throws Exception {
|
||||
this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, oneMinuteAgo))//
|
||||
.andExpect(header().dateValue(LAST_MODIFIED, currentTime));
|
||||
this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, minuteAgo))
|
||||
.andExpect(header().dateValue(LAST_MODIFIED, this.currentTime));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longValueWithCorrectResponseHeaderValue() throws Exception {
|
||||
this.mockMvc.perform(get("/persons/1"))//
|
||||
.andExpect(header().longValue("X-Rate-Limiting", 42));
|
||||
this.mockMvc.perform(get("/persons/1"))
|
||||
.andExpect(header().longValue("X-Rate-Limiting", 42));
|
||||
}
|
||||
|
||||
@Test
|
||||
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));
|
||||
this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, now))
|
||||
.andExpect(status().isNotModified())
|
||||
.andExpect(header().string("X-Custom-Header", (String) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stringWithMatcherAndMissingResponseHeader() throws Exception {
|
||||
this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, now))//
|
||||
.andExpect(status().isNotModified())//
|
||||
.andExpect(header().string("X-Custom-Header", nullValue()));
|
||||
this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, now))
|
||||
.andExpect(status().isNotModified())
|
||||
.andExpect(header().string("X-Custom-Header", nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longValueWithMissingResponseHeader() throws Exception {
|
||||
try {
|
||||
this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, now))//
|
||||
.andExpect(status().isNotModified())//
|
||||
.andExpect(header().longValue("X-Custom-Header", 99L));
|
||||
this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, now))
|
||||
.andExpect(status().isNotModified())
|
||||
.andExpect(header().longValue("X-Custom-Header", 99L));
|
||||
|
||||
fail(EXPECTED_ASSERTION_ERROR_MSG);
|
||||
fail(ERROR_MESSAGE);
|
||||
}
|
||||
catch (AssertionError e) {
|
||||
if (EXPECTED_ASSERTION_ERROR_MSG.equals(e.getMessage())) {
|
||||
if (ERROR_MESSAGE.equals(e.getMessage())) {
|
||||
throw e;
|
||||
}
|
||||
assertEquals("Response does not contain header " + "X-Custom-Header", e.getMessage());
|
||||
|
@ -138,32 +142,30 @@ public class HeaderAssertionTests {
|
|||
|
||||
@Test
|
||||
public void doesNotExist() throws Exception {
|
||||
this.mockMvc.perform(get("/persons/1"))
|
||||
.andExpect(header().doesNotExist("X-Custom-Header"));
|
||||
this.mockMvc.perform(get("/persons/1")).andExpect(header().doesNotExist("X-Custom-Header"));
|
||||
}
|
||||
|
||||
// SPR-10771
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void doesNotExistFail() throws Exception {
|
||||
this.mockMvc.perform(get("/persons/1"))
|
||||
.andExpect(header().doesNotExist(LAST_MODIFIED));
|
||||
this.mockMvc.perform(get("/persons/1")).andExpect(header().doesNotExist(LAST_MODIFIED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stringWithIncorrectResponseHeaderValue() throws Exception {
|
||||
assertIncorrectResponseHeaderValue(header().string(LAST_MODIFIED, oneSecondLater), oneSecondLater);
|
||||
assertIncorrectResponseHeader(header().string(LAST_MODIFIED, secondLater), secondLater);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stringWithMatcherAndIncorrectResponseHeaderValue() throws Exception {
|
||||
assertIncorrectResponseHeaderValue(header().string(LAST_MODIFIED, equalTo(oneSecondLater)), oneSecondLater);
|
||||
assertIncorrectResponseHeader(header().string(LAST_MODIFIED, equalTo(secondLater)), secondLater);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dateValueWithIncorrectResponseHeaderValue() throws Exception {
|
||||
long unexpected = currentTime + 1000;
|
||||
assertIncorrectResponseHeaderValue(header().dateValue(LAST_MODIFIED, unexpected), oneSecondLater);
|
||||
long unexpected = this.currentTime + 1000;
|
||||
assertIncorrectResponseHeader(header().dateValue(LAST_MODIFIED, unexpected), secondLater);
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
|
@ -171,21 +173,20 @@ public class HeaderAssertionTests {
|
|||
this.mockMvc.perform(get("/persons/1")).andExpect(header().longValue("X-Rate-Limiting", 1));
|
||||
}
|
||||
|
||||
private void assertIncorrectResponseHeaderValue(ResultMatcher resultMatcher, String unexpected) throws Exception {
|
||||
private void assertIncorrectResponseHeader(ResultMatcher matcher, String unexpected) throws Exception {
|
||||
try {
|
||||
this.mockMvc.perform(get("/persons/1").header(IF_MODIFIED_SINCE, oneMinuteAgo))//
|
||||
.andExpect(resultMatcher);
|
||||
this.mockMvc.perform(get("/persons/1")
|
||||
.header(IF_MODIFIED_SINCE, minuteAgo))
|
||||
.andExpect(matcher);
|
||||
|
||||
fail(EXPECTED_ASSERTION_ERROR_MSG);
|
||||
fail(ERROR_MESSAGE);
|
||||
}
|
||||
catch (AssertionError e) {
|
||||
if (EXPECTED_ASSERTION_ERROR_MSG.equals(e.getMessage())) {
|
||||
if (ERROR_MESSAGE.equals(e.getMessage())) {
|
||||
throw e;
|
||||
}
|
||||
// [SPR-10659] Ensure that the header name is included in the message
|
||||
//
|
||||
// We don't use assertEquals() since we cannot control the formatting
|
||||
// produced by JUnit or Hamcrest.
|
||||
// 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);
|
||||
|
@ -198,9 +199,8 @@ public class HeaderAssertionTests {
|
|||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Controller
|
||||
@SuppressWarnings("unused")
|
||||
private static class PersonController {
|
||||
|
||||
private long timestamp;
|
||||
|
@ -216,6 +216,7 @@ public class HeaderAssertionTests {
|
|||
.ok()
|
||||
.lastModified(calculateLastModified(id))
|
||||
.header("X-Rate-Limiting", "42")
|
||||
.header("Vary", "foo", "bar")
|
||||
.body(new Person("Jason"));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue