There's a struts2-junit-plugin for testing Struts2 actions, but it seems to require the tests to be written in JUnit 3 style, that is I can't use @BeforeClass, @Test etc annotations and can't use BDD-style test names like "shouldDoThisAndThat()". Is there a way to combine开发者_运维问答 struts2-junit-plugin and JUnit 4-style tests?
You may want to try this out:
http://glindholm.wordpress.com/2008/06/30/unit-testing-struts-2-actions/
I have found it to be very useful in testing Struts2 actions. It uses Mockrunner to simulate running in a servlet container, so you can develop your tests in any way you like, including using JUnit 4.
I had the same problem, here's how I solved it, its a pretty simple base class.
In my case I use hibernate, so leave out the session/transaction stuff if you aren't using it. This let's you keep using all the mock struts objects, which I found handy. A simple test case follows.
I still need to figure out how to inject resource bundles (i18n strings)... I will be adding that to the base class.
package com.accelarad.unittest;
import org.apache.struts2.StrutsTestCase;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.SessionHolder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.context.WebApplicationContext;
/**
* Bring Struts JUnit3 into the JUnit4 world
*
* @author kcostilow
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration( {
"classpath:spring-datasource-unittest.xml",
"classpath:spring-test-hibernate.xml",
"classpath:spring-context.xml",
"classpath:spring-security.xml",
"classpath:spring-server.xml"
}
)
public abstract class AbstractSpringStruts2JUnit4 extends StrutsTestCase implements ApplicationContextAware {
protected ApplicationContext applicationContext;
@Autowired
protected SessionFactory sessionFactory;
// implements ApplicationContextAware
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@BeforeClass
public static void initialize() {
// in my case, I create a mock JNDI here,
// including a mailSession using a Wiser mock SMTP server
}
@Before
public void setUp() throws Exception {
super.setUp(); // use JUnit3 setUp chain. In this case setupBeforeInitDispatcher() will be called
if (! TransactionSynchronizationManager.hasResource(sessionFactory)) {
Session session = SessionFactoryUtils.getSession(sessionFactory, true); // first @Before only
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
}
}
@Override
protected void setupBeforeInitDispatcher() throws Exception {
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext);
// inject hibernate sessionFactory into Transaction Management, simulating OpenSessionInView
}
@AfterClass
public static void shutdown() {
// in my case, I shutdown the mock mail server here
}
}
Sample test case:
public class MyActionTest extends AbstractSpringStruts2JUnit4 {
@Test
public void testOneStrutsAction() throws Exception {
ActionProxy proxy = super.getActionProxy("/packageName/actionName");
TestCase.assertEquals("actionName result", "success", proxy.execute());
MyAction myAction = (MyAction ) proxy.getAction();
TestCase.assertNotNull(myAction.getSomething());
}
}
You can take it from there I think.
For others who land here searching for how to test struts2 actions using Junit, here's some sample code using Struts2.3.12 & Junit 4
public class TestIoOptimizationAction extends StrutsJUnit4TestCase<IoOptimizationAction> {
@Test
public void login() throws Exception {
request.setParameter("email", "nitin.cool4urchat@gmail.com");
request.setParameter("password", "22");
ActionProxy proxy = getActionProxy("login");
Map<String, Object> sessionMap = new HashMap<String, Object>();
proxy.getInvocation().getInvocationContext().setSession(sessionMap);
String result = proxy.execute();
// String result = executeAction("/login");
assertEquals("success", result);
System.out.println(response.getContentAsString());
}
}
I had to separately embed session map, because I'm using getActionProxy() and here's the reason
Your test class should extend StrutsSpringJUnit4TestCase.
I stole a little bit from kcostilow and coding_idiot's answers and created an abstract class with StrutsJUnit4TestCase
:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration( {
"classpath:spring-datasource-unittest.xml",
"classpath:spring-test-hibernate.xml",
"classpath:spring-context.xml",
"classpath:spring-security.xml",
"classpath:spring-server.xml"
}
)
@Transactional
@TransactionConfiguration(transactionManager = "dataSourceTransactionManager")
public abstract class AbstractSpringStruts2JUnit4<T extends ActionSupport> extends StrutsJUnit4TestCase<T> {
@Autowired
@Qualifier("dataSource")
public void setDataSource(DataSource dataSource) {
this.dataSource= dataSource;
}
@Before
public void onSetUp() throws Exception {
super.setUp();
setupAction();
}
protected abstract void setupAction();
}
Then extended the class to create the test:
public class SomeActionIntegrationTest extends AbstractSpringStruts2JUnit4<SomeAction> {
private SomeAction someAction; // SomeAction must extend ActionSupport.
@Override
protected void setupAction() {
ActionProxy proxy = super.getActionProxy("/someAction");
// You might have* to add ".do" to the end of the URI.
So, super.getActionProxy("/someAction.do") was the only way I was able to get the proxy.
someAction = (ActionSupport) proxy.getAction();
assertNotNull(someAction);
}
@Test
public void testExecute() throws Exception {
String result = someAction.execute();
assertEquals("input", result);
}
}
精彩评论