I have a session scoped bean which holds user data per http session. I would like to write a Junit test case to test the session scoped bean. I would like to write the test case such that it can prove that the beans are getting created per session. Any pointer as how to write such Junit test case?
3 Answers
I came across this simpler approach, thought I might as well post here in case others need it.
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="session">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>
With this approach, you don't have to mock any request/session objects.
Source: http://tarunsapra.wordpress.com/2011/06/28/junit-spring-session-and-request-scope-beans/
Update for spring 5.x (works in spring 5.3.22, in a JUnit5 test, annotated by @ExtendWith(SpringExtension.class) ): The same bean definitions by annotations. Place this code somewhere in a spring configuration class:
/**
* Used in CustomScopeConfigurer bean below
*
* @return
*/
@Bean
public static SimpleThreadScope simpleThreadScope()
{
return new SimpleThreadScope();
}
/**
* This bean is needed in order to mimic spring's SessionScope
*
* @param aSimpleThreadScope
* @return
*/
@Bean
public static CustomScopeConfigurer customScopeConfigurer(SimpleThreadScope aSimpleThreadScope)
{
CustomScopeConfigurer result = new CustomScopeConfigurer();
result.addScope( "session", aSimpleThreadScope );
return result;
}
-
The same applies to 'request' scope, just use key='request' for the request scoped beans. – Zeus Sep 23 '16 at 20:46
In order to use request and session scopes in unit test you need to:
- register these scopes in application context
- create mock session and request
- register mock request via
RequestContextHolder
Something like this (assume that you use Spring TestContext to run your tests):
abstractSessionTest.xml
:
<beans ...>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="session">
<bean class="org.springframework.web.context.request.SessionScope" />
</entry>
<entry key="request">
<bean class="org.springframework.web.context.request.RequestScope" />
</entry>
</map>
</property>
</bean>
</beans>
.
@ContextConfiguration("abstractSessionTest.xml")
public abstract class AbstractSessionTest {
protected MockHttpSession session;
protected MockHttpServletRequest request;
protected void startSession() {
session = new MockHttpSession();
}
protected void endSession() {
session.clearAttributes();
session = null;
}
protected void startRequest() {
request = new MockHttpServletRequest();
request.setSession(session);
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
}
protected void endRequest() {
((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).requestCompleted();
RequestContextHolder.resetRequestAttributes();
request = null;
}
}
Now you can use these methods in your test code:
startSession();
startRequest();
// inside request
endRequest();
startRequest();
// inside another request of the same session
endRequest();
endSession();

- 239,438
- 41
- 511
- 482
Spring 3.2 and newer provides support for session/request scoped beans for integration testing
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class)
@WebAppConfiguration
public class SampleTest {
@Autowired WebApplicationContext wac;
@Autowired MockHttpServletRequest request;
@Autowired MockHttpSession session;
@Autowired MySessionBean mySessionBean;
@Autowired MyRequestBean myRequestBean;
@Test
public void requestScope() throws Exception {
assertThat(myRequestBean)
.isSameAs(request.getAttribute("myRequestBean"));
assertThat(myRequestBean)
.isSameAs(wac.getBean("myRequestBean", MyRequestBean.class));
}
@Test
public void sessionScope() throws Exception {
assertThat(mySessionBean)
.isSameAs(session.getAttribute("mySessionBean"));
assertThat(mySessionBean)
.isSameAs(wac.getBean("mySessionBean", MySessionBean.class));
}
}
References:
-
2After adding WebAppConfiguration I had an initializationError error that I solved adding the servlet-api to the pom file as stated here: http://nickebbitt.wordpress.com/2013/12/20/spring-3-2-mvc-unit-testing-initializationerror-using-webappconfiguration/ – borjab Jun 09 '14 at 16:29
-
Tipp: do not use \@WebAppConfiguration in combination with \@IntegrationTest. Does not work for me – Simon Ludwig Dec 01 '16 at 18:57