javaspringjunitstruts2actioncontext

StrutsSpringTestCase - Several contexts - How to instantiate them properly in order


I am writing integration test cases for the project that uses Struts2, Spring, Hibernate using JUnit.

My test class extends StrutsSpringTestCase. The application needs login/session to invoke any action. Following is the code:

@Test
public void testGetActionProxy() throws Exception {
    
    ActionProxy proxy;
    String result;
    ActionContext.getContext().setSession(createUserSession()); // Not sure if this is needed here. But in order to get the session working, I need this.

    proxy = initAction("cInfo");
    assertNotNull(proxy);
        
    CustInfo action = (CustInfo) proxy.getAction();
    result = proxy.execute();
    assertEquals(Action.SUCCESS, result);
}

The initAction() method:

private ActionProxy initAction(String actionUri) {
    ActionProxy proxy = getActionProxy(actionUri);
    
    ActionContext.setContext(proxy.getInvocation().getInvocationContext());  // I tried this line of code to get the ServletActionContext.getMapping().getName() to work. But no use.
    
    ActionContext actionContext = proxy.getInvocation().getInvocationContext();
    actionContext.setSession(createUserSession()); // This is for setting a session
    return proxy;
 }

Before it hits this method, it loads all the config files. struts.xml jpaContext.xml, beans.xml, etc.

My Action class CustInfo implements ServletRequestAware and it has a method getActionName which as the line:

 return ServletActionContext.getActionMapping().getName();

This gets invoked when I call result = proxy.execute();. So the request is failing.

Question 1: Why does it return null? I thought ServletActionContext is automatically initiated, so it should return a value. But its not. If its not initialized, where is the proper place to initialize and how?

I tried the following after getActionProxy call. But it still did not work.

ServletActionContext.setContext(proxy.getInvocation().getInvocationContext());

Question 2: To set the session, before getActionProxy(), I am having to call,

ActionContext.getContext().setSession(createUserSession());

And again, after getActionProxy

ActionContext actionContext = proxy.getInvocation().getInvocationContext();
actionContext.setSession(createUserSession());

to set the session. I assume, there is something wrong here.

Question 3: Looks like, there are several contexts in play here:applicationContext, ActionContext ServletContext and ServletActionContext.

When my test class extends StrutsSpringTestCase class, I guess applicationContext is initialized. But I am not sure about other contexts. Where to initialize them?

Edit:

Further investigation in the source code reveals one issue.. When I call ServletActionContext.getActionMapping(), internally its calling ActionContext's get() method.

public Object get(String key) {
    return context.get(key);
}

context is a map of object, in which its looking for value for a key struts.actionMapping, which does not exist. So, returns null. But not sure why it is there. It's not empty. It has other key/values.


Solution

  • The answer to your questions:

    ServletActionContext.getActionMapping() returns the mapping from the action context, if it's not set then you get null.

    You shouldn't set a session manually, a session is created when action is executed.

    Don't mess up different classes ActionContext, ServletContext, and ServletActionContext. You shouldn't do anything with initializing these objects, because it's done by the superclass StrutsSpringTestCase.

    public void testGetActionMapping() {
        ActionMapping mapping = getActionMapping("/cInfo.action");
        assertNotNull(mapping);
        assertEquals("/", mapping.getNamespace());
        assertEquals("cInfo", mapping.getName());
    }
    
    public void testGetActionProxy() throws Exception {        
        ActionProxy proxy = getActionProxy("/cInfo.action");
        assertNotNull(proxy);
    
        CustInfo action = (CustInfo) proxy.getAction();
        assertNotNull(action);
    
        String result = proxy.execute();
        assertEquals(Action.SUCCESS, result);
    }