简体   繁体   English

如何消除在 Spring Boot 单元测试中启用安全性的 @Configuration 类

[英]How to eliminate @Configuration classes with security enabled in Spring Boot unit testing

I am on a new microservice which is working fine and all the test cases were also working fine.我在一个新的微服务上运行良好,所有测试用例也运行良好。 Recently, the Spring Boot microservice is enabled with spring security with sso.最近,Spring Boot 微服务启用了 spring security with sso。 Microservice is working fine but test cases are getting failed because of security.微服务运行良好,但由于安全原因,测试用例失败了。 I have a class which needs to eliminated at run time during spring boot unit test.我有一个需要在 Spring Boot 单元测试期间在运行时消除的类。 I provide below the code.我在代码下方提供。

@Configuration
@Slf4j
public class CloudSecurityConfig {
    private String host = "some host";
    private String port = System.getenv("redis.port");
    private String password = System.getenv("redis.password");
    private String ssl = System.getenv("redis.ssl");
    
    @Bean
    JedisPoolConfig jedisPoolConfig(@Value("${redis.pool.maxactive}") int maxActive,
            @Value("${redis.pool.maxidle}") int maxIdle, @Value("${redis.pool.minidle}") int minIdle) {
        .... Other code
        return jedisPoolConfig;
    }
    
    @Bean
    JedisConnectionFactory jedisConnectionFactory() throws Exception {
            .... Other code
        
        return jedisConFactory;
    }

    @Bean
    @Primary
    public RedisTemplate<String, CtmUser> redisTemplate() throws Exception {
        .... Other code
        return redisTemplate;
    }
}

I have also tried with this link Java Spring Boot Test: How to exclude java configuration class from test context .我也尝试过这个链接Java Spring Boot Test: How to exclude java configuration class from test context But it is not working.但它不起作用。 I get the following error details.我收到以下错误详细信息。

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate<?, ?>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1717) ~[spring-beans-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1273) ~[spring-beans-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227) ~[spring-beans-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ~[spring-beans-5.2.10.RELEASE.jar:5.2.10.RELEASE]
    ... 84 common frames omitted

The above is coming from the class CloudSecurityConfig .以上来自CloudSecurityConfig类。 I think, if I am able to remove this configuration, everything will work fine.我想,如果我能够删除这个配置,一切都会正常的。

The above error is followed by the below error:上面的错误后面跟着下面的错误:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'customAuthenticationProvider': Unsatisfied dependency expressed through field 'template'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate<?, ?>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

I have tried with the following options.我尝试了以下选项。

//@EnableMongoRepositories
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration()
@SpringBootTest(classes = { ValidationApplication.class, TestMongoConfiguration.class })
//@ImportAutoConfiguration(classes = {ValidationApplication.class,TestMongoConfiguration.class})
//@EnableAutoConfiguration(exclude={ DataSourceAutoConfiguration.class, RedisAutoConfiguration.class,
//        RedisRepositoriesAutoConfiguration.class, MongoAutoConfiguration.class })

//@EnableAutoConfiguration(exclude={ DataSourceAutoConfiguration.class, RedisAutoConfiguration.class,
//      RedisRepositoriesAutoConfiguration.class, MongoAutoConfiguration.class, SecurityAutoConfiguration.class })

//@EnableAutoConfiguration(exclude={ CloudSecurityConfig.class })

//@TestPropertySource(inheritProperties = false, properties = 
//        "spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration")
//@TestConfiguration()
//@ConditionalOnProperty(name = "test", havingValue="test")
@ActiveProfiles("test")
@ComponentScan(basePackages = {"com.a.b.c.d"}
, excludeFilters = {
    @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = {SecurityCloudConfig.class})})
public class CheckTest {

    @Autowired
    private MyController controller;
    
    @Test
    void testAllBeforeEntry() {
        ResponseEntity<?> re = controller.getValdiations();
        boolean flag = re.getStatusCode().is2xxSuccessful();
        assertEquals(true, flag);
    }

}

Instead of ignoring it would be better to override the configure class.与其忽略,不如覆盖 configure 类。 You could write the appropriate TestConfiguration classes for the test env.您可以为测试环境编写适当的 TestConfiguration 类。 An example is added here:这里添加了一个例子:


@TestConfiguration
public class TestSecurityConfig {

    @Bean
    @Primary
    JedisPoolConfig jedisPoolConfig(@Value("${redis.pool.maxactive}") int maxActive,
            @Value("${redis.pool.maxidle}") int maxIdle, @Value("${redis.pool.minidle}") int minIdle) {
          // your test environment specific code/configuration.
    }

    @Bean
    JedisConnectionFactory jedisConnectionFactory() throws Exception {
            .... Other code
        // test environment specific code.
    }
    // .... Other configurations which needs to be override.

    

Note: Don't forget to add @Primary in test Beans and spring.main.allow-bean-definition-overriding=true in test application.properties file.注意:不要忘记在 test Beans 中添加@Primary并在 test application.properties 文件中添加@Primary spring.main.allow-bean-definition-overriding=true And add @SpringBootTest(classes = TestSecurityConfig.class) in main unit test class to override the original Beans.并在主单元测试类中添加@SpringBootTest(classes = TestSecurityConfig.class)以覆盖原始 Bean。

You could also supply MockBean instead of real one.您也可以提供 MockBean 而不是真正的 MockBean。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM