From f219d9e468ec54de71d4498e3fe9beccc83b6683 Mon Sep 17 00:00:00 2001 From: Maurizio Cucchiara Date: Thu, 4 Aug 2011 15:12:44 +0000 Subject: [PATCH] WW-3667 - StrutsJUnit4TestCase does not provide the executeAction method git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@1153904 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/struts2/StrutsJUnit4TestCase.java | 162 +++++++++++++++++- .../struts2/StrutsSpringJUnit4TestCase.java | 45 +++++ .../org/apache/struts2/StrutsTestCase.java | 38 ++-- 3 files changed, 218 insertions(+), 27 deletions(-) create mode 100644 plugins/junit/src/main/java/org/apache/struts2/StrutsSpringJUnit4TestCase.java diff --git a/plugins/junit/src/main/java/org/apache/struts2/StrutsJUnit4TestCase.java b/plugins/junit/src/main/java/org/apache/struts2/StrutsJUnit4TestCase.java index 0ab97ccfe..0a39bd043 100644 --- a/plugins/junit/src/main/java/org/apache/struts2/StrutsJUnit4TestCase.java +++ b/plugins/junit/src/main/java/org/apache/struts2/StrutsJUnit4TestCase.java @@ -1,16 +1,49 @@ +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + package org.apache.struts2; -import com.opensymphony.xwork2.XWorkJUnit4TestCase; +import com.opensymphony.xwork2.*; +import com.opensymphony.xwork2.config.Configuration; import com.opensymphony.xwork2.interceptor.annotations.After; import com.opensymphony.xwork2.interceptor.annotations.Before; import com.opensymphony.xwork2.util.logging.LoggerFactory; import com.opensymphony.xwork2.util.logging.jdk.JdkLoggerFactory; import org.apache.struts2.dispatcher.Dispatcher; +import org.apache.struts2.dispatcher.mapper.ActionMapper; +import org.apache.struts2.dispatcher.mapper.ActionMapping; import org.apache.struts2.util.StrutsTestCaseHelper; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.mock.web.MockPageContext; import org.springframework.mock.web.MockServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.UnsupportedEncodingException; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.HashMap; import java.util.Map; import java.util.logging.ConsoleHandler; import java.util.logging.Formatter; @@ -18,8 +51,17 @@ import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; +import static org.junit.Assert.assertNotNull; -public class StrutsJUnit4TestCase extends XWorkJUnit4TestCase { + +public class StrutsJUnit4TestCase extends XWorkJUnit4TestCase { + protected MockHttpServletResponse response; + protected MockHttpServletRequest request; + protected MockPageContext pageContext; + protected MockServletContext servletContext; + protected Map dispatcherInitParams; + + protected DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); static { ConsoleHandler handler = new ConsoleHandler(); @@ -50,6 +92,115 @@ public class StrutsJUnit4TestCase extends XWorkJUnit4TestCase { LoggerFactory.setLoggerFactory(new JdkLoggerFactory()); } + /** + * gets an object from the stack after an action is executed + */ + protected Object findValueAfterExecute(String key) { + return ServletActionContext.getValueStack(request).findValue(key); + } + + /** + * gets an object from the stack after an action is executed + * @return The executed action + */ + @SuppressWarnings("unchecked") + protected T getAction() { + return (T) findValueAfterExecute("action"); + } + + protected boolean containsErrors() { + T action = this.getAction(); + if(action instanceof ValidationAware) { + return ((ValidationAware) action).hasActionErrors(); + } + throw new UnsupportedOperationException("Current action does not implement ValidationAware interface"); + } + + /** + * Executes an action and returns it's output (not the result returned from + * execute()), but the actual output that would be written to the response. + * For this to work the configured result for the action needs to be + * FreeMarker, or Velocity (JSPs can be used with the Embedded JSP plugin) + */ + protected String executeAction(String uri) throws ServletException, UnsupportedEncodingException { + request.setRequestURI(uri); + ActionMapping mapping = getActionMapping(request); + + assertNotNull(mapping); + Dispatcher.getInstance().serviceAction(request, response, servletContext, mapping); + + if (response.getStatus() != HttpServletResponse.SC_OK) + throw new ServletException("Error code [" + response.getStatus() + "], Error: [" + + response.getErrorMessage() + "]"); + + return response.getContentAsString(); + } + + /** + * Creates an action proxy for a request, and sets parameters of the ActionInvocation to the passed + * parameters. Make sure to set the request parameters in the protected "request" object before calling this method. + */ + protected ActionProxy getActionProxy(String uri) { + request.setRequestURI(uri); + ActionMapping mapping = getActionMapping(request); + String namespace = mapping.getNamespace(); + String name = mapping.getName(); + String method = mapping.getMethod(); + + Configuration config = configurationManager.getConfiguration(); + ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy( + namespace, name, method, new HashMap(), true, false); + + ActionContext invocationContext = proxy.getInvocation().getInvocationContext(); + invocationContext.setParameters(new HashMap(request.getParameterMap())); + // set the action context to the one used by the proxy + ActionContext.setContext(invocationContext); + + // this is normaly done in onSetUp(), but we are using Struts internal + // objects (proxy and action invocation) + // so we have to hack around so it works + ServletActionContext.setServletContext(servletContext); + ServletActionContext.setRequest(request); + ServletActionContext.setResponse(response); + + return proxy; + } + + /** + * Finds an ActionMapping for a given request + */ + protected ActionMapping getActionMapping(HttpServletRequest request) { + return Dispatcher.getInstance().getContainer().getInstance(ActionMapper.class).getMapping(request, + Dispatcher.getInstance().getConfigurationManager()); + } + + /** + * Finds an ActionMapping for a given url + */ + protected ActionMapping getActionMapping(String url) { + MockHttpServletRequest req = new MockHttpServletRequest(); + req.setRequestURI(url); + return getActionMapping(req); + } + + /** + * Injects dependencies on an Object using Struts internal IoC container + */ + protected void injectStrutsDependencies(Object object) { + Dispatcher.getInstance().getContainer().inject(object); + } + + + protected void setupBeforeInitDispatcher() throws Exception { + } + + protected void initServletMockObjects() { + servletContext = new MockServletContext(resourceLoader); + response = new MockHttpServletResponse(); + request = new MockHttpServletRequest(); + pageContext = new MockPageContext(servletContext, request, response); + } + /** * Sets up the configuration settings, XWork configuration, and * message resources @@ -58,12 +209,13 @@ public class StrutsJUnit4TestCase extends XWorkJUnit4TestCase { public void setUp() throws Exception { super.setUp(); - initDispatcher(null); - + initServletMockObjects(); + setupBeforeInitDispatcher(); + initDispatcher(dispatcherInitParams); } protected Dispatcher initDispatcher(Map params) { - Dispatcher du = StrutsTestCaseHelper.initDispatcher(new MockServletContext(), params); + Dispatcher du = StrutsTestCaseHelper.initDispatcher(servletContext, params); configurationManager = du.getConfigurationManager(); configuration = configurationManager.getConfiguration(); container = configuration.getContainer(); diff --git a/plugins/junit/src/main/java/org/apache/struts2/StrutsSpringJUnit4TestCase.java b/plugins/junit/src/main/java/org/apache/struts2/StrutsSpringJUnit4TestCase.java new file mode 100644 index 000000000..74f47dcf5 --- /dev/null +++ b/plugins/junit/src/main/java/org/apache/struts2/StrutsSpringJUnit4TestCase.java @@ -0,0 +1,45 @@ +/* + * $Id$ + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.struts2; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.web.context.WebApplicationContext; + +/** + * User: mcucchiara + * Date: 04/08/11 + * Time: 16.50 + */ +public class StrutsSpringJUnit4TestCase extends StrutsJUnit4TestCase implements ApplicationContextAware { + protected ApplicationContext applicationContext; + + @Override + protected void setupBeforeInitDispatcher() throws Exception { + this.servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext); + } + + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } +} diff --git a/plugins/junit/src/main/java/org/apache/struts2/StrutsTestCase.java b/plugins/junit/src/main/java/org/apache/struts2/StrutsTestCase.java index 416b359db..d755d6914 100644 --- a/plugins/junit/src/main/java/org/apache/struts2/StrutsTestCase.java +++ b/plugins/junit/src/main/java/org/apache/struts2/StrutsTestCase.java @@ -21,21 +21,13 @@ package org.apache.struts2; -import java.io.UnsupportedEncodingException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.ConsoleHandler; -import java.util.logging.Formatter; -import java.util.logging.Level; -import java.util.logging.LogRecord; -import java.util.logging.Logger; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionProxy; +import com.opensymphony.xwork2.ActionProxyFactory; +import com.opensymphony.xwork2.XWorkTestCase; +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.util.logging.LoggerFactory; +import com.opensymphony.xwork2.util.logging.jdk.JdkLoggerFactory; import org.apache.struts2.dispatcher.Dispatcher; import org.apache.struts2.dispatcher.mapper.ActionMapper; import org.apache.struts2.dispatcher.mapper.ActionMapping; @@ -46,13 +38,15 @@ import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockPageContext; import org.springframework.mock.web.MockServletContext; -import com.opensymphony.xwork2.ActionContext; -import com.opensymphony.xwork2.ActionProxy; -import com.opensymphony.xwork2.ActionProxyFactory; -import com.opensymphony.xwork2.XWorkTestCase; -import com.opensymphony.xwork2.config.Configuration; -import com.opensymphony.xwork2.util.logging.LoggerFactory; -import com.opensymphony.xwork2.util.logging.jdk.JdkLoggerFactory; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.UnsupportedEncodingException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.*; /** * Base test case for JUnit testing Struts.