title: Disabling RedisHttpSessionConfiguration in junit tests
body: <p>I'm using <code>spring-boot</code> and <code>spring-session</code> to build a simple rest api. The production application should use the redis-session implementation, whereas the tests should use the default (non-redis) spring-session.</p>
  
  <p>However when the <code>spring-boot-starter-redis</code> maven dependency is declared in the project, spring-boot will automagically create a <code>org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration</code> without the <code>@EnableRedisHttpSession</code> annotation being anywhere in the test configuration.</p>
  
  <p>My setup</p>
  
  <p>Application code:</p>
  
  <pre class="lang-java prettyprint-override"><code>// base session config for both prod/dev and test/ci
  public class BaseSessionConfig {
  
    @Bean
    public HeaderHttpSessionStrategy sessionStrategy() {
      return new HeaderHttpSessionStrategy();
    }
  
  }
  
  // enable the redis session only in these profiles
  @Configuration
  @EnableRedisHttpSession
  @Profile({"prod", "dev", "local", "vagrant"})
  public class RedisSessionConfig extends BaseSessionConfig {
  
  
  }
  </code></pre>
  
  <p>Tests: </p>
  
  <pre class="lang-java prettyprint-override"><code>@WebIntegrationTest
  @RunWith(SpringJUnit4ClassRunner.class)
  @SpringApplicationConfiguration(classes = {MyApplication.class, MyTestApplicationConfig.class})
  public class AuthenticationResourceTest {
  
    private RestTemplate restTemplate = new TestRestTemplate();
  
    @Test
    public void testUnauthenticated() {
  
      HttpHeaders headers = restTemplate.getForEntity("http://localhost:8080/api/session", String.class).getHeaders();
  
      // ...    
    }
  
  }
  
  // session configuration for the test environments
  // no redis enabled    
  @Configuration
  @Profile({"ci", "test"})
  public class MyTestApplicationConfig extends BaseSessionConfig {
  
  
  }
  </code></pre>
  
  <p>How can i disable the redis session auto-configuration inside the junit tests?</p>
  
  <p>The stack trace during tests:</p>
  
  <pre><code>java.lang.IllegalStateException: Failed to load ApplicationContext
  
      at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
      at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
      at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
      at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
      at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:228)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:230)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:249)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
      at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
      at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
      at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
      at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
      at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
      at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
      at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
  Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer' defined in class path resource [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
      at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
      at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
      at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
      at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
      at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
      at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
      at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:764)
      at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:357)
      at org.springframework.boot.SpringApplication.run(SpringApplication.java:305)
      at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:98)
      at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
      at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
      ... 24 more
  Caused by: org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
      at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:162)
      at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:251)
      at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:58)
      at org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration$EnableRedisKeyspaceNotificationsInitializer.afterPropertiesSet(RedisHttpSessionConfiguration.java:166)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
      at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
      ... 40 more
  Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
      at redis.clients.util.Pool.getResource(Pool.java:50)
      at redis.clients.jedis.JedisPool.getResource(JedisPool.java:99)
      at redis.clients.jedis.JedisPool.getResource(JedisPool.java:12)
      at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:155)
      ... 45 more
  Caused by: redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused
      at redis.clients.jedis.Connection.connect(Connection.java:164)
      at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:82)
      at redis.clients.jedis.BinaryJedis.connect(BinaryJedis.java:1641)
      at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:85)
      at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:868)
      at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:435)
      at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:363)
      at redis.clients.util.Pool.getResource(Pool.java:48)
      ... 48 more
  Caused by: java.net.ConnectException: Connection refused
      at java.net.PlainSocketImpl.socketConnect(Native Method)
      at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
      at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
      at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
      at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
      at java.net.Socket.connect(Socket.java:589)
      at redis.clients.jedis.Connection.connect(Connection.java:158)
      ... 55 more
  </code></pre>
  
  <h2>Edit</h2>
  
  <p>I figured it out. The reason why the <code>RedisHttpSessionConfig</code> is loaded in tests despite not having the <code>EnableRedisSession</code> annotation on the config is this auto-configuration which comes with spring-boot-starter-web: <a href="https://github.com/spring-projects/spring-boot/blob/9681df0e9f8790b0d30f032a6460a957289ea05b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionAutoConfiguration.java#L51" rel="nofollow">SessionAutoConfiguration</a></p>
  
  <p>So in tests, this is the class which needs to be excluded from autoconfiguration:</p>
  
  <pre><code>@WebIntegrationTest
  @RunWith(SpringJUnit4ClassRunner.class)
  @SpringApplicationConfiguration(classes = TestAppConfig.class)
  public class AuthenticationResourceTest {
  
    private RestTemplate restTemplate = new TestRestTemplate();
  
    @Test
    public void testUnauthenticated() {
  
      HttpHeaders headers = restTemplate.getForEntity("http://localhost:8080/api/session", String.class).getHeaders();
  
    }
  
  }
  
  
  @Configuration
  @SpringBootApplication(exclude = {SessionAutoConfiguration.class, SessionRedisHttpConfiguration.class})
  public class TestAppConfig {
  
    @Configuration
    static class SessionConfig extends BaseSessionConfig {
  
    }
  
  }
  </code></pre>