【问题标题】:Disable spring session with redis in integrationtests在集成测试中禁用 redis 的 spring 会话
【发布时间】:2017-06-09 05:17:39
【问题描述】:

我正在使用带有 redis 的 spring session,但我想在进行测试时禁用它。我的班级被注释了:

@ActiveProfiles("integrationtests")

我的 application-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-server,测试会起作用,但我当然不想保持这种状态; )

//更新

我一直在尝试

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

和排除 Redis 的 Application.class:

@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 autoconfigure debug 看到我排除了这个类,但是没有效果:

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

org.springframework.boot.autoconfigure.session.SessionAutoConfiguration

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

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

【问题讨论】:

  • ive 解决方法如下:stackoverflow.com/questions/33008798/…,但主要问题仍然存在 - 为什么排除 redis 类不排除它们? :)
  • 知道在测试期间很难始终准备好一个 redis 实例,我建议您将这个属性 spring.session.store-type=hash_map 用于您的测试用例

标签: java spring redis spring-session spring-data-redis


【解决方案1】:

我在测试时用来解决此 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 {
}

【讨论】:

    【解决方案2】:

    创建一个“测试”配置文件特定的 yml (application-test.yml)

    session.session.store-type=none
    

    并且测试类应该有注释

    @ActiveProfiles("test")
    

    【讨论】:

    • 这应该是测试中的spring.session.store-type=noneapplication.properties
    【解决方案3】:

    没有直接的解决方案,但可以解决,比如下面的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 {
    
    }
    

    另一个 @EnableRedisHttpSession 用于所有其他配置文件,例如 dev、staging 和 prod,类似于下面的 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

    【讨论】:

    • 我明天会尝试,在我的评论(最后一个)中提供更多信息:github.com/spring-projects/spring-session/issues/332 - 即使将 RedisHttpSessionConfiguration 添加到排除的类,它也会在这个类中失败,并出现“UnsatisfiedDependencyException”:/跨度>
    • 不,它没有帮助,我添加了 @EnableAutoConfiguration(exclude = {SessionAutoConfiguration.class, RedisAutoConfiguration.class, RedisHttpSessionConfiguration.class}) @ActiveProfiles("integrationtests") 它仍然失败,现在:在类路径资源 [org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.class] 中定义名称为“enableRedisKeyspaceNotificationsInitializer”的 bean 创建错误:
    • @Arpit 嗨,Arpit 我是 Redis 的新手,你能解释一下如何将 Redis 与 Spring Boot 集成吗?我们需要手动安装 redis 还是只需要在 POM 中安装 Dependecies 就足够了。
    猜你喜欢
    • 1970-01-01
    • 2018-02-08
    • 2019-05-08
    • 1970-01-01
    • 1970-01-01
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多