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", "em...@email.com");
        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 <m...@raibledesigns.com>
> 
> 
> On Tue, Dec 14, 2010 at 5:47 AM, Josep García <jgar...@isigma.es> 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:m...@raibledesigns.com";>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?
> 
> 
> 

Reply via email to