001 package com.mockrunner.mock.web; 002 003 import org.apache.struts.Globals; 004 import org.apache.struts.action.ActionMapping; 005 006 import com.mockrunner.struts.ActionMappingProxyGenerator; 007 008 /** 009 * Used to create all types of struts mock objects. Maintains 010 * the necessary dependencies between the mock objects. 011 * If you use the mock objects returned by this 012 * factory in your tests you can be sure that they are all 013 * up to date. 014 */ 015 public class ActionMockObjectFactory extends WebMockObjectFactory 016 { 017 private MockActionMapping mockMapping; 018 private ActionMapping mapping; 019 private MockActionServlet mockActionServlet; 020 private MockModuleConfig mockModuleConfig; 021 022 /** 023 * Creates a new set of mock objects. 024 */ 025 public ActionMockObjectFactory() 026 { 027 createMockObjects(); 028 } 029 030 /** 031 * Creates a set of mock objects based on another one. 032 * The created mock objects will have their own 033 * request and session objects, but they will share 034 * one <code>ServletContext</code>. 035 * @param factory the other factory 036 * @see com.mockrunner.base.BaseTestCase#createWebMockObjectFactory(WebMockObjectFactory) 037 */ 038 public ActionMockObjectFactory(WebMockObjectFactory factory) 039 { 040 super(factory); 041 createMockObjects(); 042 } 043 044 /** 045 * Creates a set of mock objects based on another one. 046 * You can specify, if the created mock objects should 047 * share the same session. They will share one 048 * <code>ServletContext</code> anyway. 049 * @param factory the other factory 050 * @param createNewSession <code>true</code> creates a new session, 051 * <code>false</code> uses the session from factory 052 * @see com.mockrunner.base.BaseTestCase#createWebMockObjectFactory(WebMockObjectFactory, boolean) 053 */ 054 public ActionMockObjectFactory(WebMockObjectFactory factory, boolean createNewSession) 055 { 056 super(factory, createNewSession); 057 createMockObjects(); 058 } 059 060 private void createMockObjects() 061 { 062 mockMapping = createMockActionMapping(); 063 mapping = mockMapping; 064 mockModuleConfig = createMockModuleConfig(); 065 mockActionServlet = createMockActionServlet(); 066 mockActionServlet.setServletConfig(getMockServletConfig()); 067 mockActionServlet.setServletContext(getMockServletContext()); 068 refresh(); 069 } 070 071 /** 072 * Refreshes the mock objects dependencies. May be called after setting request 073 * and response wrappers. 074 */ 075 public void refresh() 076 { 077 super.refresh(); 078 getWrappedRequest().setAttribute(Globals.MAPPING_KEY, mapping); 079 getWrappedRequest().setAttribute(Globals.MODULE_KEY, mockModuleConfig); 080 } 081 082 /** 083 * Creates the {@link com.mockrunner.mock.web.MockActionServlet} using <code>new</code>. 084 * This method can be overridden to return a subclass of {@link com.mockrunner.mock.web.MockActionServlet}. 085 * @return the {@link com.mockrunner.mock.web.MockActionServlet} 086 */ 087 public MockActionServlet createMockActionServlet() 088 { 089 return new MockActionServlet(); 090 } 091 092 /** 093 * Creates the {@link com.mockrunner.mock.web.MockModuleConfig} using <code>new</code>. 094 * This method can be overridden to return a subclass of {@link com.mockrunner.mock.web.MockModuleConfig}. 095 * @return the {@link com.mockrunner.mock.web.MockModuleConfig} 096 */ 097 public MockModuleConfig createMockModuleConfig() 098 { 099 return new MockModuleConfig("testmodule"); 100 } 101 102 /** 103 * Creates the {@link com.mockrunner.mock.web.MockActionMapping} using <code>new</code>. 104 * This method can be overridden to return a subclass of {@link com.mockrunner.mock.web.MockActionMapping}. 105 * @return the {@link com.mockrunner.mock.web.MockActionMapping} 106 */ 107 public MockActionMapping createMockActionMapping() 108 { 109 return new MockActionMapping(); 110 } 111 112 /** 113 * Prepares an <code>ActionMapping</code>. If your actions rely 114 * on a custom subclass of <code>ActionMapping</code>, use this 115 * method to prepare it. Since {@link com.mockrunner.struts.ActionTestModule} 116 * relies on the behaviour of {@link com.mockrunner.mock.web.MockActionMapping}, 117 * this method creates a subclass CGLib proxy of the specified mapping class. 118 * You can cast the returned <code>ActionMapping</code> to your custom 119 * mapping class and the subclass proxy will redirect the necessary 120 * methods to the {@link com.mockrunner.mock.web.MockActionMapping}. 121 * Redirected are methods for retrieving forwards. If an <code>ActionMapping</code> 122 * is prepared, {@link #getActionMapping} returns the prepared mapping while 123 * {@link #getMockActionMapping} returns the the underlying {@link com.mockrunner.mock.web.MockActionMapping}. 124 * This method relies on CGLib. CGLib is not required by the Struts test framework 125 * if this method is not used. 126 * @param mappingClass the class of the custom action mapping 127 * @return an instance of the custom action mapping class 128 */ 129 public ActionMapping prepareActionMapping(Class mappingClass) 130 { 131 ActionMappingProxyGenerator generator = new ActionMappingProxyGenerator(mockMapping); 132 mapping = generator.createActionMappingProxy(mappingClass); 133 refresh(); 134 return mapping; 135 } 136 137 /** 138 * Resets <code>ActionMapping</code> configuration, i.e. sets 139 * the current <code>ActionMapping</code> returned by {@link #getActionMapping} 140 * to the mock action mapping returned by {@link #getMockActionMapping}. 141 */ 142 public void resetActionMapping() 143 { 144 mapping = mockMapping; 145 } 146 147 /** 148 * Returns the <code>ActionMapping</code>. Unless you prepare an 149 * <code>ActionMapping</code> using {@link #prepareActionMapping}, 150 * this method returns the same object as {@link #getMockActionMapping}. 151 * If an <code>ActionMapping</code> is prepared, this method returns 152 * the prepared <code>ActionMapping</code> while {@link #getMockActionMapping} 153 * returns the underlying {@link com.mockrunner.mock.web.MockActionMapping}. 154 * @return the <code>ActionMapping</code> 155 */ 156 public ActionMapping getActionMapping() 157 { 158 return mapping; 159 } 160 161 /** 162 * Returns the {@link com.mockrunner.mock.web.MockActionMapping}. 163 * @return the {@link com.mockrunner.mock.web.MockActionMapping} 164 */ 165 public MockActionMapping getMockActionMapping() 166 { 167 return mockMapping; 168 } 169 170 /** 171 * Returns the {@link com.mockrunner.mock.web.MockModuleConfig}. 172 * @return the {@link com.mockrunner.mock.web.MockModuleConfig} 173 */ 174 public MockModuleConfig getMockModuleConfig() 175 { 176 return mockModuleConfig; 177 } 178 179 /** 180 * Returns the {@link com.mockrunner.mock.web.MockActionServlet}. 181 * @return the {@link com.mockrunner.mock.web.MockActionServlet} 182 */ 183 public MockActionServlet getMockActionServlet() 184 { 185 return mockActionServlet; 186 } 187 }