Question

I am writing acceptance tests (testing the behavior) using cucumber-jvm, on an application with Struts 2 and Tomcat as my Servlet Container. At some point in my code, I need to fetch the user from the Struts 2 HttpSession, created by an HttpServletRequest.

Since I'm doing tests and not running Tomcat, I don't have an active session and I get a NullPointerException.

Here's the code I need to call:

public final static getActiveUser() {
    return (User) getSession().getAttribute("ACTIVE_USER");
}

And the getSession method:

public final static HttpSession getSession() {
    final HttpServletRequest request (HttpServletRequest)ActionContext.
                          getContext().get(StrutsStatics.HTTP_REQUEST);
    return request.getSession();
}

In all honesty, I don't know much about Struts 2, so I need a little help. I've been looking at this cucumber-jvm with embedded tomcat example, but I'm struggling to understand.

I've also been looking at this Struts 2 Junit Tutorial. Sadly, it doesn't cover very well all the StrutsTestCase features and it's the simplest of use cases (all considered, a pretty useless tutorial).

So, how can I run my acceptance test as if the user was using the application?


UPDATE:

Thanks to Steven Benitez for the answer!

I had to do two things:

  1. Mock the HttpServletRequest, as suggested,
  2. Mock the HttpSession to get the attribute I wanted.

here's the code I've added to my cucumber-jvm tests:

public class StepDefs {
    User user;
    HttpServletRequest request;
    HttpSession session;

    @Before
    public void prepareTests() {
        // create a user

        // mock the session using mockito
        session = Mockito.mock(HttpSession.class);
        Mockito.when(session.getAttribute("ACTIVE_USER").thenReturn(user);

        // mock the HttpServletRequest
        request = Mockito.mock(HttpServletRequest);
        Mockito.when(request.getSession()).thenReturn(session);

        // set the context
        Map<String, Object> contextMap = new HashMap<String, Object>();
        contextMap.put(StrutsStatics.HTTP_REQUEST, request);
        ActionContext.setContext(new ActionContext(contextMap));
    }

    @After
    public void destroyTests() {
        user = null;
        request = null;
        session = null;
        ActionContext.setContext(null);
    }

}

Was it helpful?

Solution

An ActionContext is a per-request object that represents the context in which an action executes. The static methods getContext() and setContext(ActionContext context) are backed by a ThreadLocal. In this case, you can call this before your test:

Map<String, Object> contextMap = new HashMap<String, Object>();
contextMap.put(StrutsStatics.HTTP_REQUEST, yourMockHttpServletRequest);
ActionContext.setContext(new ActionContext(contextMap));

And then clean it up after with:

ActionContext.setContext(null);

This example will only provide what the method you are testing needs. If you need additional entries in the map based on code you didn't provide here, then just add them accordingly.

Hope that helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top