在集成测试中禁用使用Redis的Spring Session

5

我正在使用Spring Session和Redis,但是在进行测试时我想要禁用它。我的类被注释为:

@ActiveProfiles("integrationtests")

我的应用程序integrationtests.tml文件包含:

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

但它仍然失败,显示如下:
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

如果我打开redis服务器,测试可以正常工作,但是我当然不想一直保持这种状态 ; )

//更新

我一直在尝试使用

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

并且将Application.class与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);
}
}

但是它失败了,报错为:

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

Spring自动配置调试显示我已经排除了这个类,但是没有效果:

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

org.springframework.boot.autoconfigure.session.SessionAutoConfiguration

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

org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration

我已经通过这里的方法解决了它:https://dev59.com/t4_ea4cB1Zd3GeqPUOFT#36203419,但主要问题仍然存在 - 为什么排除Redis类不会将它们排除? :) - hi_my_name_is
考虑到在测试期间始终准备好 Redis 实例很困难,我建议您在测试用例中使用此属性 spring.session.store-type=hash_map - imarchuang
3个回答

3

当我在进行测试时,解决Redis依赖问题的方法是使用@ConditionalOnProperty注解,并在测试时设置一个属性(testing=true)。

请使用以下代码进行会话配置:

@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();
        }
    }
}

以下是单元测试的代码:

@RunWith(SpringRunner.class)
@TestPropertySource(properties = "testing=true")
@SpringBootTest(classes = Application.class)
public class MyTest {
}

3
创建一个针对"test"环境的配置文件(application-test.yml)。
spring.session.store-type=none

测试类应该有注释

@ActiveProfiles("test")

3
在测试的 application.properties 文件中,应该写成 spring.session.store-type=none。请注意,翻译时需要保留原意并使其更加通俗易懂,不得添加解释或其他内容。 - Ashley Frieze

0

没有直接的解决方案,但是有一个变通方法,比如下面的Test类:

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

    @Autowired
    private StudentRepository studentRepository;

    @Test
    public void test() {
    }

}

您可以创建包含所有配置的基类,例如:

@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();
    }
}

为无@EnableRedisHttpSession的集成测试创建子类

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

}

另外一个是针对所有其他配置文件(如dev、staging和prod)的,使用@EnableRedisHttpSession,与下面的dev类似:

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

}

你可以选择将dev作为Spring Boot应用程序的默认配置文件,方法是在application.properties中指定spring.profiles.active,如下所示:

spring.profiles.active=dev

例如,您可以参考arpitaggarwal/spring-boot-redis


我明天会尝试一下,在我的评论中还有更多信息(最后一个):https://github.com/spring-projects/spring-session/issues/332 - 即使将RedisHttpSessionConfiguration添加到排除的类中,仍然会出现“UnsatisfiedDependencyException”错误,就在这个类中:/ - hi_my_name_is
不行,这并没有帮助。我已经添加了@EnableAutoConfiguration(exclude = {SessionAutoConfiguration.class, RedisAutoConfiguration.class, RedisHttpSessionConfiguration.class})和@ActiveProfiles("integrationtests")。但它仍然失败了,现在出现了以下错误: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
@Arpit 你好,Arpit。我对Redis还不熟悉,请问你能否解释一下如何将Redis与Spring Boot集成?我们需要手动安装Redis吗,还是只需要在POM中添加依赖即可? - mohit bansal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接