7

So, Im using spring session in my project. How to write integration tests in project using it? Should I mock something for spring session internals? Or any reasonable way to use embedded redis?

I saw there was some @EnableEmbeddedRedis annotation in past, but seems it was removed: https://github.com/spring-projects/spring-session/issues/248

//edit

Ive tried to pass MockHttpSession to

mockMvc.perform(post("/register").session(mockHttpSession)

but spring tries and fails to connect to redis anyway.

hi_my_name_is
  • 4,894
  • 3
  • 34
  • 50

4 Answers4

12

You can create your own connectionfactory and the redisserializer. Then spring boot won't create their default beans.

Example:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
public class ApplicationTest
{

    @Test
    public void contextLoads()
    {
    }


    @EnableRedisHttpSession
    @Configuration
    static class Config
    {
        @Bean
        @SuppressWarnings("unchecked")
        public RedisSerializer<Object> defaultRedisSerializer()
        {
            return Mockito.mock(RedisSerializer.class);
        }


        @Bean
        public RedisConnectionFactory connectionFactory()
        {
            RedisConnectionFactory factory = Mockito.mock(RedisConnectionFactory.class);
            RedisConnection connection = Mockito.mock(RedisConnection.class);
            Mockito.when(factory.getConnection()).thenReturn(connection);

            return factory;
        }
    }
}
Patrick Cornelissen
  • 7,968
  • 6
  • 48
  • 70
2

I would not suggest to use mockHttpSession, as it will bypass the integration with spring-session library in the tests. I would

@RunWith(SpringRunner.class)
@SpringBootTest
@WebAppConfiguration
public class ExampleControllerV2SpringSessionTest {

@Autowired
private WebApplicationContext wac;

@Autowired
private SessionRepository sessionRepository;

@Autowired
private SessionRepositoryFilter sessionRepositoryFilter;

//this is needed to test spring-session specific features
private MockMvc mockMvcWithSpringSession;

@Before
public void setup() throws URISyntaxException {

this.mockMvcWithSpringSession = MockMvcBuilders
   .webAppContextSetup(wac)
   .addFilter(sessionRepositoryFilter)
   .build();
}
}

Knowing that it's hard to always have 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
  • 467
  • 7
  • 17
1

ok, ive just disabled redis by using profiles in my integration tests

@ActiveProfiles("integrationtests")
class RegisterControllerTest extends Specification {...

and extracting @EnableRedisHttpSession to its own class:

@Configuration
@EnableRedisHttpSession
@Profile("!integrationtests")
public class RedisConfig {

}

Its more like workaround than solution, but I dont need to test anything inside session anyway.

hi_my_name_is
  • 4,894
  • 3
  • 34
  • 50
  • 1
    Just a note...This won't work if you use Spring Boot. Spring Boot uses autoconfiguration for setting Redis connection (when you have redis-session on your classpath Spring Boot search for the Redis connection and fail if nothing was found.) – shobull Apr 04 '16 at 14:18
  • it was spring boot, but version below 1.4, maybe even below 1.3, in 1.4 is like you said - autoconfiguration fetch in redis. – hi_my_name_is Jan 25 '17 at 08:22
0

This work:

In your HttpSessionConfig define profiles where the configuration is active:

@EnableRedisHttpSession
@Profile("prod")
class HttpSessionConfig {

}

In application-prod.properties add:

#REDIS SERVER
spring.redis.host=xxxxxxxx

And then in your application.properties of test add:

#REDIS SERVER
spring.data.redis.repositories.enabled=false
spring.session.store-type=none