5

I am using spring session with redis, but I want to disable it while doing tests. My class is annotated:

@ActiveProfiles("integrationtests")

and my application-integrationtests.tml file contains:

spring.autoconfigure.exclude: org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration

but it still fails with:

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

tests work if I turn redis-server on, but ofcourse I dont want to keep it that way ; )

//update

ive been trying with

@SpringBootTest(classes = {Application.class})
@ActiveProfiles("integrationtests")

and Application.class with excluded Redis:

@SpringBootApplication(exclude={SessionAutoConfiguration.class, RedisAutoConfiguration.class, RedisHttpSessionConfiguration.class})
public class Application {

public static void main(String[] args) throws Exception {
    SpringApplication.run(Application.class, args);
}
}

but it fails with:

Error creating bean with name 'redisMessageListenerContainer' defined in class path resource [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class]

spring autoconfigure debug see that Ive excluded this class, but it has no effect:

Exclusions:
-----------

org.springframework.boot.autoconfigure.session.SessionAutoConfiguration

org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration

org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration
Arpit Aggarwal
  • 27,626
  • 16
  • 90
  • 108
hi_my_name_is
  • 4,894
  • 3
  • 34
  • 50
  • ive workaround it as here: http://stackoverflow.com/questions/33008798/spring-session-with-redis-how-to-mock-it-in-integration-tests/36203419#36203419 , but main question remains - why excluding redis classes dont exclude them? :) – hi_my_name_is Jan 25 '17 at 11:25
  • Knowing that it's hard to always have a redis instance ready during the test, I would suggest you to use this property `spring.session.store-type=hash_map` for your test cases – imarchuang Jan 01 '18 at 04:15

3 Answers3

3

The workaround I use to solve this Redis dependency while testing is to use the @ConditionalOnProperty annotation and setting a property (testing=true) while testing.

Use the following code for session configuration:

@Configuration
public class SessionConfig {
    @ConditionalOnProperty(name = "testing", havingValue = "false", matchIfMissing = true)
    @EnableRedisHttpSession
    public static class RedisSessionConfig {
    }

    @ConditionalOnProperty(name = "testing", havingValue = "true")
    @EnableSpringHttpSession
    public static class MapSessionConfig {
        @Bean
        public SessionRepository<ExpiringSession> sessionRepository() {
            return new MapSessionRepository();
        }
    }
}

And the following code for the unit test:

@RunWith(SpringRunner.class)
@TestPropertySource(properties = "testing=true")
@SpringBootTest(classes = Application.class)
public class MyTest {
}
Italo Borssatto
  • 15,044
  • 7
  • 62
  • 88
3

Create a "test" profile specific yml (application-test.yml)

spring.session.store-type=none

and the test class should have the annotation

@ActiveProfiles("test")
Christoffer Hammarström
  • 27,242
  • 4
  • 49
  • 58
DJones
  • 31
  • 2
0

No direct solution but yes there is a work around, say for Test class below:

@SpringBootTest(classes = { ApplicationConfig.class })
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("integrationtests")
public class SpringBootRedisApplicationTest {

    @Autowired
    private StudentRepository studentRepository;

    @Test
    public void test() {
    }

}

You can create Base class with all the configuration, as:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.spring.boot.redis.repository" })
public class ApplicationConfig {

    @Bean
    public JedisConnectionFactory jedisConnFactory() {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
        jedisConnectionFactory.setUsePool(true);
        jedisConnectionFactory.setHostName("localhost");
        jedisConnectionFactory.setPort(6379);
        return jedisConnectionFactory;
    }

    @SuppressWarnings("rawtypes")
    @Bean
    public RedisTemplate redisTemplate() {
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(jedisConnFactory());
        return redisTemplate;
    }

    @Bean
    public RedisHttpSessionConfiguration redisHttpSessionConfiguration() {
        return new RedisHttpSessionConfiguration();
    }
}

And subclass for integration test with no @EnableRedisHttpSession

@Configuration
@Profile({ "integrationtests", "unittest" })
public class IntegrationTestConfig extends ApplicationConfig {

}

And another with @EnableRedisHttpSession for all other profiles like dev, staging and prod, similar to dev below:

@Profile({ "dev" })
@Configuration
@EnableRedisHttpSession
public class DevConfig extends ApplicationConfig {

}

Optionally, you can make dev as default profile for spring boot app specifying spring.profiles.active in application.properties, as:

spring.profiles.active=dev

For sample example, you can refer arpitaggarwal/spring-boot-redis

Arpit Aggarwal
  • 27,626
  • 16
  • 90
  • 108
  • I will try tomorrow, some more info in my comment (last one ): https://github.com/spring-projects/spring-session/issues/332 - even when RedisHttpSessionConfiguration is added to excluded classes it fails with 'UnsatisfiedDependencyException' in exactly this class : / – hi_my_name_is Jan 24 '17 at 19:37
  • nope, it did not help, ive added @EnableAutoConfiguration(exclude = {SessionAutoConfiguration.class, RedisAutoConfiguration.class, RedisHttpSessionConfiguration.class}) @ActiveProfiles("integrationtests") it still fails, now with: Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer' defined in class path resource [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class]: – hi_my_name_is Jan 25 '17 at 06:59
  • @Arpit Hi Arpit I am new for Redis, Could you please explain me how to integrate redis with spring boot? Do we need to install the redis manually or only Dependecies is enough in POM. – mohit bansal Mar 23 '17 at 06:19