Ok. Josep. This is what we are using today. Pasting this in the email seems
long, but....
@ContextConfiguration(loader=StrutsContextLoader.class , locations =
{"classpath:/applicationContext-resources.xml",
"classpath:/applicationContext-CrowdClient.xml"
,"classpath:/applicationContext-dao.xml"
,"classpath:/applicationContext-service.xml"
,"classpath:/applicationContext-web.xml"
,"classpath:/applicationContext.xml"
,"/WEB-INF/security.xml" })
@TransactionConfiguration(transactionManager =
"transactionManager",defaultRollback = true)
@Transactional
public abstract class BaseStrutsTestCase extends
AbstractTransactionalJUnit4SpringContextTests{
protected MockHttpServletRequest request;
protected MockHttpServletResponse response;
private Dispatcher dispatcher;
protected ActionProxy proxy;
WebApplicationContext context;
@Before
public void onSetUpBeforeTransaction() throws Exception {
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
context = (WebApplicationContext)applicationContext;
HashMap params = new HashMap();
dispatcher = new Dispatcher(context.getServletContext(), params);
dispatcher.init();
Dispatcher.setInstance(dispatcher);
}
@After
public void onTearDownAfterTransaction() throws Exception{
request = null;
response = null;
context = null;
dispatcher = null;
proxy = null;
}
protected <T> T createAction(String namespace, String name)
throws Exception {
Map extraContext = dispatcher.createContextMap(request, response, null,
context.getServletContext());
proxy = dispatcher.getContainer().getInstance(ActionProxyFactory.class).
createActionProxy(
namespace, name, null,extraContext, true, false);
proxy.getInvocation().getInvocationContext().
setSession(new HashMap());
//set to false when using convention plugin
proxy.setExecuteResult(false);
ServletActionContext.setContext(
proxy.getInvocation().getInvocationContext());
ServletActionContext.setServletContext(context.getServletContext());
return (T) proxy.getAction();
}
public void setUpMockSecurityManager(RootAction action, User user) {
MockSecurityService securityService = (MockSecurityService)
context.getBean("mockSecurityService");
if (user != null)
securityService.setUser(user);
action.setSecurityService(securityService);
}
And then we use:
public class StrutsContextLoader extends AbstractContextLoader {
static final Log log = LogFactory.getLog(StrutsContextLoader.class);
public ApplicationContext loadContext(String... locations) throws Exception
{
MockServletContext servletContext = new
MockServletContext("/src/main/webapp/",new FileSystemResourceLoader());
servletContext.addInitParameter(ContextLoader.CONFIG_LOCATION_PARAM,
arrayToString(locations, ","));
return (new ContextLoader()).initWebApplicationContext(servletContext);
}
protected String getResourceSuffix() {
return null;
}
public static String arrayToString(String[] a, String separator) {
StringBuffer result = new StringBuffer();
if (a.length > 0) {
result.append(a[0]);
for (int i = 1; i < a.length; i++) {
result.append(separator);
result.append(a[i]);
}
}
return result.toString();
}
}
And here is an example of a Unit Test:
public class EventControllerTest extends BaseStrutsTestCase {
private static final Log log = LogFactory.getLog(EventControllerTest.class);
EventController controller;
@Autowired
EventMessageQueue eventMessageQueue;
@Autowired
EventService eventService;
@Test
public void create() throws Exception {
request.setParameter("event.name", "Test Event");
request.setParameter("event.shortDescription", "Short Description");
request.setParameter("event.summaryText", "Summary Text");
request.setParameter("event.longDescription", "Long Description");
request.setParameter("event.department", "Cardiology");
request.setParameter("event.subjects", "Healthy Heart");
request.setParameter("event.subjects", "Cancer Institute");
request.setParameter("event.preRequisites", "Text Pre-requisites");
request.setParameter("event.cost", "25.00");
request.setParameter("event.maxRegistrations", "25");
request.setParameter("event.contactPhone", "925-222-2321");
request.setParameter("event.contactEmail", "[email protected]");
request.setParameter("event.schedulingType", "STANDARD");
controller = createAction("/events", "create");
String result = proxy.execute();
Assert.assertEquals("success", result);
Assert.assertNotNull(controller.getEvent().getId());
boolean foundOurMessage = false;
Long messageIdToFind = controller.getEvent().getId();
while (eventMessageQueue.size() > 0) {
EventMessage message = eventMessageQueue.pop();
log.debug("Processing message : " + message.getEvent().getId());
if (message.getEvent().getId() == messageIdToFind)
foundOurMessage = true;
}
Assert.assertTrue("Couldn't find our message in the queue.",
foundOurMessage);
}
@Test
public void update() throws Exception {
request.setParameter("event.id", "1");
request.setParameter("event.name", "New Name");
controller = createAction("/events", "update");
String result = proxy.execute();
Assert.assertEquals("success", result);
Assert.assertEquals("New Name", controller.getEvent().getName());
}
}
So the general usage is:
Setup your request.
Create your action
proxy.execute()
Inspect the action for changes after the call
Note:
In BaseStrutsTestCase the line:
proxy.setExecuteResult(false);
if set to true will make sure your results are there. We had problems with it
and the Convention plugin a while ago so we set it false. We don't really
need that level of testing here since all of the views are tested via Selenium
anyways.
SecurityManager is specific to our application and its integration with Crowd
so it doesn't do anything for your needs.
-D
On Dec 14, 2010, at 7:19 AM, Josep García wrote:
> This seems to be based on servletunit and it looks like it only supports
> Struts 1.x.
>
> I'd like to write a test like:
>
> public void testSearchByBondName() throws Exception {
> HashMap params = new HashMap();
>
> ActionProxy proxy = createActionProxy(NAMESPACE, ACTION, parrams);
> assertEquals("success", proxy.invoke());
> assertTrue(action.getActionErrors().isEmpty());
> }
>
> I was trying some solutions for this, based on what I found on the net, like:
> http://depressedprogrammer.wordpress.com/2007/06/18/unit-testing-struts-2-actions-spring-junit/
>
> but with no luck when accessing the persistent objects in my actions.
>
> org.hibernate.LazyInitializationException: could not initialize proxy - no
> Session
> at
> org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57)
> at
> org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111)
> at
> org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150)
>
> Incidentally, I found a org.apache.struts2.StrutsTestCase class, but there
> seems to be no examples on how to use it.
>
> Josep
>
> 2010/12/14 Matt Raible <[email protected]>
>
>
> On Tue, Dec 14, 2010 at 5:47 AM, Josep García <[email protected]> wrote:
> I have found this while doing some search:
>
>
> /**
> * This class is extended by all ActionTests. It basically
> * contains common methods that they might use.
> *
> * <p>
> * <a href="BaseStrutsTestCase.java.html"><i>View Source</i></a>
> *
> * @author <a href="mailto:[email protected]">Matt Raible</a>
> */
> public abstract class BaseStrutsTestCase extends MockStrutsTestCase {
>
> However, in my AppFuse 2.0.2, ActionTests extend BaseActionTestCase. This
> lacks the possibility of testing action messages, struts validation, etc.
>
> Where is this appfuse BaseStrutsTestCase availble? Can it be used to test
> struts validation and so on?
>
> Yes, you should be able to test these things. What does your test case look
> like and what's not working?
>
>
>