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 }