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