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.
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;
}
}
}
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.
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.
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
来源:https://stackoverflow.com/questions/33008798/spring-session-with-redis-how-to-mock-it-in-integration-tests