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.
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);
}