In response to a comment made to Unit Testing Struts 2.0, here is the updated, complete code for Struts 2.0 testing. Hope this is useful. Have questions ? Want to discuss any of this ? Just drop me a line...Read on, includes support class code, small snippets for creation of Spring beans, Struts 2.0 actions, Struts 2.0 action proxies.
/** * Class for easier support of Struts related * testing. Takes care of all the configuration details * that allow test classes to create beans (Spring), * actions (Struts), intercepted actions (Struts). * Class is singleton to minimize hit of initializing * Struts and related infrastructure (e.g. Hibernate). * * @author Francisco Assis Rosa */ public class StrutsTestCaseSupport {
/** * Singleton variable */ public static StrutsTestCaseSupport _theInstance;
/** * Singleton access */ public static synchronized StrutsTestCaseSupport getInstance() { if ( _theInstance == null ) { _theInstance = new StrutsTestCaseSupport(); } return _theInstance; }
/** * Application context class (encapsulation of applicationContext.xml) */ ConfigurableWebApplicationContext _applicationContext;
/** * Configuration Manager object, to allow for encapusulation of struts.xml, * creation of actions and their proxied counterparts, creation of * servlet context from this application context */ ConfigurationManager _configurationManager;
/** * Class constructor, take care of Struts initializations */ private StrutsTestCaseSupport () {
// create the struts+spring integrated object factory // set spring autowiring by name for spring object factory Settings.set(StrutsConstants.STRUTS_OBJECTFACTORY_SPRING_AUTOWIRE,"name"); StrutsSpringObjectFactory objectFactory = new StrutsSpringObjectFactory();
// set system object facory ObjectFactory.setObjectFactory(objectFactory);
// set action proxy factory ActionProxyFactory.setFactory(new StrutsActionProxyFactory());
// create a web application context instance (for spring configuration) _applicationContext = new XmlWebApplicationContext();
// get ahold of a servlet context to use in the creation of the application context ServletContext servletContext = createOneServletContext(_applicationContext); // complete application context initialization, pass in servlet // context and config file location, force reading of config (via refresh) _applicationContext.setServletContext(servletContext); _applicationContext.setConfigLocations(new String[] {"WEB-INF/applicationContext.xml"}); _applicationContext.refresh();
// initialize the object factory with the mock servlet context, application context objectFactory.init(servletContext); objectFactory.setApplicationContext(_applicationContext);
// add a default dispatcher to the system Dispatcher du = new Dispatcher(servletContext); Dispatcher.setInstance(du);
// pass over to the configuration manager location where struts-default.xml, // struts-plugin.xml and struts.xml can be found, force reading all _configurationManager = new ConfigurationManager(); _configurationManager.addConfigurationProvider( new StrutsXmlConfigurationProvider("struts-default.xml", false)); _configurationManager.addConfigurationProvider( new StrutsXmlConfigurationProvider("struts-plugin.xml", false)); _configurationManager.addConfigurationProvider( new StrutsXmlConfigurationProvider("struts.xml", false)); _configurationManager.reload(); }
/** * create a servlet context useable for a specific action * * @param applicationContext the application context to use in the servlet context * @return the created servlet context */ protected ServletContext createOneServletContext (ConfigurableWebApplicationContext applicationContext) { // create a servlet context for this action, use FileSystemResourceLoader for // context to find configuration files ServletContext servletContext = (ServletContext) new MockServletContext(new FileSystemResourceLoader());
// initialize freemarker manager config parameter to null (let FreemarkerManager figure // out configuration location out of ServletContext) Settings.set(StrutsConstants.STRUTS_I18N_ENCODING, "UTF-8"); servletContext.setAttribute(FreemarkerManager.CONFIG_SERVLET_CONTEXT_KEY,null);
// hand over application context to servlet context servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext);
return servletContext; }
/** * Build one action context for an accessmethod and an access url * * @param serverName the hostname that the request will need to hook up to * @param accessMethod http method to use (e.g. 'get', 'post', 'put', etc) * @param accessUrl the url to access * @return the map for the action's context * @throws Exception on processing, configuration errors, test failure */ public Map
Or to do a full fledged Struts 2.0 action proxy test:
// create action for ActionSearchTest Map requestParameters = new HashMap(); requestParameters.put("searchMode","quick"); requestParameters.put("searchText","Testing"); Map actionContext = StrutsTestCaseSupport.getInstance().buildActionContext("struts.assisrosa.com","get","/search/results",requestParameters);
// create the proxy for the action, this encapsulates all // the interception stack up to the real action ActionProxy proxy = StrutsTestCaseSupport.getInstance().createActionProxy("results","/search",actionContext);
// let the full stack run String result = proxy.execute();
// confirm result, any exception thrown will cause test to fail assert result.equals("success");
Or a Struts 2.0 action test (no proxy in front of it):