001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.test.web.servlet.result; 018 019import java.util.concurrent.Callable; 020import javax.servlet.http.HttpServletRequest; 021 022import org.hamcrest.Matcher; 023 024import org.springframework.mock.web.MockHttpServletRequest; 025import org.springframework.test.web.servlet.MvcResult; 026import org.springframework.test.web.servlet.ResultMatcher; 027import org.springframework.web.context.request.async.DeferredResult; 028import org.springframework.web.context.request.async.WebAsyncTask; 029 030import static org.hamcrest.MatcherAssert.*; 031import static org.springframework.test.util.AssertionErrors.*; 032 033/** 034 * Factory for assertions on the request. 035 * 036 * <p>An instance of this class is typically accessed via 037 * {@link MockMvcResultMatchers#request}. 038 * 039 * @author Rossen Stoyanchev 040 * @author Sam Brannen 041 * @since 3.2 042 */ 043public class RequestResultMatchers { 044 045 /** 046 * Protected constructor. 047 * <p>Use {@link MockMvcResultMatchers#request()}. 048 */ 049 protected RequestResultMatchers() { 050 } 051 052 053 /** 054 * Assert whether asynchronous processing started, usually as a result of a 055 * controller method returning {@link Callable} or {@link DeferredResult}. 056 * <p>The test will await the completion of a {@code Callable} so that 057 * {@link #asyncResult(Matcher)} can be used to assert the resulting value. 058 * Neither a {@code Callable} nor a {@code DeferredResult} will complete 059 * processing all the way since a {@link MockHttpServletRequest} does not 060 * perform asynchronous dispatches. 061 */ 062 public ResultMatcher asyncStarted() { 063 return new ResultMatcher() { 064 @Override 065 public void match(MvcResult result) { 066 HttpServletRequest request = result.getRequest(); 067 assertAsyncStarted(request); 068 } 069 }; 070 } 071 072 /** 073 * Assert that asynchronous processing was not started. 074 * @see #asyncStarted() 075 */ 076 public ResultMatcher asyncNotStarted() { 077 return new ResultMatcher() { 078 @Override 079 public void match(MvcResult result) { 080 HttpServletRequest request = result.getRequest(); 081 assertEquals("Async started", false, request.isAsyncStarted()); 082 } 083 }; 084 } 085 086 /** 087 * Assert the result from asynchronous processing with the given matcher. 088 * <p>This method can be used when a controller method returns {@link Callable} 089 * or {@link WebAsyncTask}. 090 */ 091 public <T> ResultMatcher asyncResult(final Matcher<T> matcher) { 092 return new ResultMatcher() { 093 @Override 094 @SuppressWarnings("unchecked") 095 public void match(MvcResult result) { 096 HttpServletRequest request = result.getRequest(); 097 assertAsyncStarted(request); 098 assertThat("Async result", (T) result.getAsyncResult(), matcher); 099 } 100 }; 101 } 102 103 /** 104 * Assert the result from asynchronous processing. 105 * <p>This method can be used when a controller method returns {@link Callable} 106 * or {@link WebAsyncTask}. The value matched is the value returned from the 107 * {@code Callable} or the exception raised. 108 */ 109 public <T> ResultMatcher asyncResult(final Object expectedResult) { 110 return new ResultMatcher() { 111 @Override 112 public void match(MvcResult result) { 113 HttpServletRequest request = result.getRequest(); 114 assertAsyncStarted(request); 115 assertEquals("Async result", expectedResult, result.getAsyncResult()); 116 } 117 }; 118 } 119 120 /** 121 * Assert a request attribute value with the given Hamcrest {@link Matcher}. 122 */ 123 public <T> ResultMatcher attribute(final String name, final Matcher<T> matcher) { 124 return new ResultMatcher() { 125 @Override 126 @SuppressWarnings("unchecked") 127 public void match(MvcResult result) { 128 T value = (T) result.getRequest().getAttribute(name); 129 assertThat("Request attribute '" + name + "'", value, matcher); 130 } 131 }; 132 } 133 134 /** 135 * Assert a request attribute value. 136 */ 137 public <T> ResultMatcher attribute(final String name, final Object expectedValue) { 138 return new ResultMatcher() { 139 @Override 140 public void match(MvcResult result) { 141 assertEquals("Request attribute '" + name + "'", expectedValue, result.getRequest().getAttribute(name)); 142 } 143 }; 144 } 145 146 /** 147 * Assert a session attribute value with the given Hamcrest {@link Matcher}. 148 */ 149 public <T> ResultMatcher sessionAttribute(final String name, final Matcher<T> matcher) { 150 return new ResultMatcher() { 151 @Override 152 @SuppressWarnings("unchecked") 153 public void match(MvcResult result) { 154 T value = (T) result.getRequest().getSession().getAttribute(name); 155 assertThat("Session attribute '" + name + "'", value, matcher); 156 } 157 }; 158 } 159 160 /** 161 * Assert a session attribute value. 162 */ 163 public <T> ResultMatcher sessionAttribute(final String name, final Object value) { 164 return new ResultMatcher() { 165 @Override 166 public void match(MvcResult result) { 167 assertEquals("Session attribute '" + name + "'", value, result.getRequest().getSession().getAttribute(name)); 168 } 169 }; 170 } 171 172 private static void assertAsyncStarted(HttpServletRequest request) { 173 assertEquals("Async started", true, request.isAsyncStarted()); 174 } 175 176}