001 package com.mockrunner.mock.web; 002 003 import java.lang.reflect.Constructor; 004 005 import javax.servlet.http.HttpServletRequest; 006 import javax.servlet.http.HttpServletResponse; 007 008 import com.mockrunner.base.NestedApplicationException; 009 010 /** 011 * Used to create all types of web mock objects. Maintains 012 * the necessary dependencies between the mock objects. 013 * If you use the mock objects returned by this 014 * factory in your tests you can be sure, they are all 015 * up to date. 016 */ 017 public class WebMockObjectFactory 018 { 019 private HttpServletRequest wrappedRequest; 020 private HttpServletResponse wrappedResponse; 021 private MockHttpServletRequest request; 022 private MockHttpServletResponse response; 023 private MockServletConfig config; 024 private MockServletContext context; 025 private MockHttpSession session; 026 private MockPageContext pageContext; 027 private MockFilterConfig filterConfig; 028 private MockFilterChain filterChain; 029 030 /** 031 * Creates a new set of mock objects. 032 */ 033 public WebMockObjectFactory() 034 { 035 createMockObjects(); 036 } 037 038 /** 039 * Creates a set of mock objects based on another one. 040 * The created mock objects will have their own 041 * request and session objects, but they will share 042 * one <code>ServletContext</code>. 043 * @param factory the other factory 044 * @see com.mockrunner.base.BaseTestCase#createWebMockObjectFactory(WebMockObjectFactory) 045 */ 046 public WebMockObjectFactory(WebMockObjectFactory factory) 047 { 048 createMockObjectsBasedOn(factory); 049 } 050 051 /** 052 * Creates a set of mock objects based on another one. 053 * You can specify, if the created mock objects should 054 * share the same session. They will share one 055 * <code>ServletContext</code> anyway. 056 * @param factory the other factory 057 * @param createNewSession <code>true</code> creates a new session, 058 * <code>false</code> uses the session from factory 059 * @see com.mockrunner.base.BaseTestCase#createWebMockObjectFactory(WebMockObjectFactory, boolean) 060 */ 061 public WebMockObjectFactory(WebMockObjectFactory factory, boolean createNewSession) 062 { 063 createMockObjectsBasedOn(factory, createNewSession); 064 } 065 066 private void createMockObjects() 067 { 068 createNewMockObjects(true); 069 config = new MockServletConfig(); 070 context = new MockServletContext(); 071 setUpDependencies(); 072 } 073 074 private void createMockObjectsBasedOn(WebMockObjectFactory factory) 075 { 076 createMockObjectsBasedOn(factory, true); 077 } 078 079 private void createMockObjectsBasedOn(WebMockObjectFactory factory, boolean createNewSession) 080 { 081 createNewMockObjects(createNewSession); 082 if(!createNewSession) session = factory.getMockSession(); 083 config = factory.getMockServletConfig(); 084 context = factory.getMockServletContext(); 085 setUpDependencies(); 086 } 087 088 private void createNewMockObjects(boolean createNewSession) 089 { 090 request = new MockHttpServletRequest(); 091 response = new MockHttpServletResponse(); 092 wrappedRequest = request; 093 wrappedResponse = response; 094 if(createNewSession) session = new MockHttpSession(); 095 filterChain = new MockFilterChain(); 096 filterConfig = new MockFilterConfig(); 097 } 098 099 private void setUpDependencies() 100 { 101 config.setServletContext(context); 102 request.setSession(session); 103 session.setupServletContext(context); 104 pageContext = new MockPageContext(config, request, response); 105 filterConfig.setupServletContext(context); 106 } 107 108 /** 109 * Refreshes the mock objects dependencies. May be called after setting request 110 * and response wrappers. 111 */ 112 public void refresh() 113 { 114 pageContext = new MockPageContext(config, wrappedRequest, wrappedResponse); 115 } 116 117 /** 118 * Returns the <code>MockServletConfig</code> 119 * @return the <code>MockServletConfig</code> 120 */ 121 public MockServletConfig getMockServletConfig() 122 { 123 return config; 124 } 125 126 /** 127 * Returns the {@link com.mockrunner.mock.web.MockServletContext}. 128 * @return the {@link com.mockrunner.mock.web.MockServletContext} 129 */ 130 public MockServletContext getMockServletContext() 131 { 132 return context; 133 } 134 135 /** 136 * Returns the {@link com.mockrunner.mock.web.MockHttpServletRequest}. 137 * @return the {@link com.mockrunner.mock.web.MockHttpServletRequest} 138 */ 139 public MockHttpServletRequest getMockRequest() 140 { 141 return request; 142 } 143 144 /** 145 * Returns the {@link com.mockrunner.mock.web.MockHttpServletResponse}. 146 * @return the {@link com.mockrunner.mock.web.MockHttpServletResponse} 147 */ 148 public MockHttpServletResponse getMockResponse() 149 { 150 return response; 151 } 152 153 /** 154 * Returns the wrapped <code>HttpServletRequest</code>. If no 155 * wrapper is specified, this method returns the mock request itself. 156 * @return the wrapped <code>HttpServletRequest</code> 157 */ 158 public HttpServletRequest getWrappedRequest() 159 { 160 return wrappedRequest; 161 } 162 163 /** 164 * Returns the wrapped <code>HttpServletResponse</code>. If no 165 * wrapper is specified, this method returns the mock response itself. 166 * @return the wrapped <code>HttpServletRequest</code> 167 */ 168 public HttpServletResponse getWrappedResponse() 169 { 170 return wrappedResponse; 171 } 172 173 /** 174 * Returns the {@link com.mockrunner.mock.web.MockHttpSession}. 175 * @return the {@link com.mockrunner.mock.web.MockHttpSession} 176 */ 177 public MockHttpSession getMockSession() 178 { 179 return session; 180 } 181 182 /** 183 * Returns the {@link com.mockrunner.mock.web.MockHttpSession}. 184 * @return the {@link com.mockrunner.mock.web.MockHttpSession} 185 * @deprecated use {@link #getMockSession} 186 */ 187 public MockHttpSession getSession() 188 { 189 return getMockSession(); 190 } 191 192 /** 193 * Returns the {@link com.mockrunner.mock.web.MockPageContext}. 194 * @return the {@link com.mockrunner.mock.web.MockPageContext} 195 */ 196 public MockPageContext getMockPageContext() 197 { 198 return pageContext; 199 } 200 201 /** 202 * Returns the {@link com.mockrunner.mock.web.MockFilterConfig}. 203 * @return the {@link com.mockrunner.mock.web.MockFilterConfig} 204 */ 205 public MockFilterConfig getMockFilterConfig() 206 { 207 return filterConfig; 208 } 209 210 /** 211 * Returns the {@link com.mockrunner.mock.web.MockFilterChain}. 212 * @return the {@link com.mockrunner.mock.web.MockFilterChain} 213 */ 214 public MockFilterChain getMockFilterChain() 215 { 216 return filterChain; 217 } 218 219 /** 220 * Can be used to add a request wrapper. All the 221 * test modules are using the wrapped request returned by 222 * {@link #getWrappedRequest}. The method {@link #getMockRequest} 223 * returns the mock request without any wrapper. 224 * Usually the wrapper is of type <code>javax.servlet.http.HttpServletRequestWrapper</code>. 225 * That's not absolutely necessary but the wrapper must define a constructor 226 * that takes a single <code>javax.servlet.http.HttpServletRequest</code> argument 227 * and must implement <code>javax.servlet.http.HttpServletRequest</code>. 228 * @param wrapper the wrapper class 229 */ 230 public void addRequestWrapper(Class wrapper) 231 { 232 try 233 { 234 Constructor constructor = wrapper.getConstructor(new Class[] {HttpServletRequest.class}); 235 wrappedRequest = (HttpServletRequest)constructor.newInstance(new Object[] {wrappedRequest}); 236 } 237 catch(Exception exc) 238 { 239 throw new NestedApplicationException(exc); 240 } 241 } 242 243 /** 244 * Can be used to add a request wrapper. 245 * All the test modules are using the wrapped request returned by 246 * {@link #getWrappedRequest}. The method {@link #getMockRequest} 247 * returns the mock request without any wrapper. Usually the wrapper is 248 * an instance of <code>javax.servlet.http.HttpServletRequestWrapper</code> 249 * and wraps the current request but that's not absolutely necessary. 250 * However, be careful if you want to add custom mock versions of 251 * <code>javax.servlet.http.HttpServletRequest</code>. 252 * @param wrapper the request wrapper 253 */ 254 public void addRequestWrapper(HttpServletRequest wrapper) 255 { 256 wrappedRequest = wrapper; 257 } 258 259 /** 260 * Can be used to add a response wrapper. All the 261 * test modules are using the wrapped response returned by 262 * {@link #getWrappedResponse}. The method {@link #getMockResponse} 263 * returns the mock response without any wrapper. 264 * Usually the wrapper is of type <code>javax.servlet.http.HttpServletResponseWrapper</code>. 265 * That's not absolutely necessary but the wrapper must define a constructor 266 * that takes a single <code>javax.servlet.http.HttpServletResponse</code> argument 267 * and must implement <code>javax.servlet.http.HttpServletResponse</code>. 268 * @param wrapper the wrapper class 269 */ 270 public void addResponseWrapper(Class wrapper) 271 { 272 try 273 { 274 Constructor constructor = wrapper.getConstructor(new Class[] {HttpServletResponse.class}); 275 wrappedResponse = (HttpServletResponse)constructor.newInstance(new Object[] {wrappedResponse}); 276 } 277 catch(Exception exc) 278 { 279 throw new NestedApplicationException(exc); 280 } 281 } 282 283 /** 284 * Can be used to add a response wrapper. 285 * All the test modules are using the wrapped response returned by 286 * {@link #getWrappedResponse}. The method {@link #getMockResponse} 287 * returns the mock response without any wrapper. Usually the wrapper is 288 * an instance of <code>javax.servlet.http.HttpServletResponseWrapper</code> 289 * and wraps the current response but that's not absolutely necessary. 290 * However, be careful if you want to add custom mock versions of 291 * <code>javax.servlet.http.HttpServletResponse</code>. 292 * @param wrapper the wrapper 293 */ 294 public void addResponseWrapper(HttpServletResponse wrapper) 295 { 296 wrappedResponse = wrapper; 297 } 298 }