Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
spring scanner为所有测试拾取了带有@Configuration的内部静态类。怎么了?_Spring_Spring Boot_Junit - Fatal编程技术网

spring scanner为所有测试拾取了带有@Configuration的内部静态类。怎么了?

spring scanner为所有测试拾取了带有@Configuration的内部静态类。怎么了?,spring,spring-boot,junit,Spring,Spring Boot,Junit,Spring从Test2中获取Test1的内部@Configuration。在Test2中我需要一个模拟的IService,但在Test1中需要一个真正的serviceinpl。此外,我还希望为所有测试提供公共TestConfiguration。但在两次测试中,我总是嘲笑iSeries。怎么了 如何禁用兄弟测试的内部配置拾取 这是我的密码: ServiceImpl.java: @Service public class SeriviveImpl implements IService { }

Spring从Test2中获取Test1的内部
@Configuration
。在Test2中我需要一个模拟的
IService
,但在Test1中需要一个真正的
serviceinpl
。此外,我还希望为所有测试提供公共
TestConfiguration
。但在两次测试中,我总是嘲笑iSeries。怎么了

如何禁用兄弟测试的内部配置拾取

这是我的密码:

ServiceImpl.java:

@Service
public class SeriviveImpl implements IService {
}
TestConfiguration.java:

@Configuration
@ComponentScan
public class TestConfiguration {
   // empty
}
Test1.java:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestConfiguration.class})
public class Test1 {
    @Autowired
    private IService service;
}
Test2.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Test2.CustomConfiguration.class, TestConfiguration.class})
public class Test2 {
    @Autowired
    private IService service;

    @Configuration
    static class CustomConfiguration {
        @Bean
        IService service() {
            return mock(IService.class);
        }
    }
}

您可以通过使用
org.springframework.beans.factory.annotation.Qualifier
annotation显式选择所需的实现来实现这一点。下面是您的代码可能的样子:

...
@Service 
@Qualifier("impl")
public class SeriviveImpl implements IService {}
...
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestConfiguration.class})
public class Test1 {
   @Autowired
   @Qualifier("impl")
   private IService service;
}
...
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Test2.CustomConfiguration.class,TestConfiguration.class})
public class Test2 {
   @Autowired
   @Qualifer("mock")
   private IService service;

   @Configuration
   static class CustomConfiguration {
       @Bean
       @Qualifier("mock")
       IService service() { return mock(IService.class); }
   }
} 

您可以从TestConfiguration@ComponentScan筛选内部类:

@Configuration
@ComponentScan(excludeFilters = {
     @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
                           value = Test2.CustomConfiguration.class)
})
public class TestConfiguration {
   // empty
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
public @interface InnerConfiguration {
}
这将防止它在Test1中被拾取

编辑或者,如果您有很多内部配置,您可以创建自己的注释,并从@ComponentScan中筛选所有这些注释类:

@Configuration
@ComponentScan(excludeFilters = {
     @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
                           value = Test2.CustomConfiguration.class)
})
public class TestConfiguration {
   // empty
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
public @interface InnerConfiguration {
}
然后在内部类上使用此注释,而不是@Configuration:

@InnerConfiguration
    static class CustomConfiguration {
        @Bean
        IService service() {
            return mock(IService.class);
        }
    }
并从组件扫描中过滤这些内容,如下所示:

@Configuration
@ComponentScan(excludeFilters = {
     @ComponentScan.Filter(type = FilterType.ANNOTATION,
                           value = InnerConfiguration.class)
})
public class TestConfiguration {
   // empty
}

由于在
Test2
@ContextConfiguration
注释中显式使用
Test2.CustomConfiguration.class
,因此可以从
Test2.CustomConfiguration
中删除
@Configuration
注释,并且在
Test1
运行期间,
@ComponentScan
不会拾取该注释

这是因为:

使用带注释的 类(请参见基于Java的容器配置),您可以对 使用@ContextConfiguration测试类并配置这些类 属性,该属性的数组包含对注释类的引用

术语“注释类”可以指任何 以下:

用@Configuration注释的类

组件(即,用@component、@Service、, @存储库或其他原型注释)

一个JSR-330兼容类,用javax.inject注释 注释

包含@Bean方法的任何其他类。


我想一定还有别的办法。将@Qualifier添加到实现中,因为测试配置相交不是我的方式。是的,我可以,但TestConfiguration现在对Test2的了解是不好的。TestConfiguration理想情况下不应该知道本地子配置。它知道,因为您正在扫描组件,@Configuration是一个组件。这就是春天的工作原理。如果你不想让它把它捡起来,那么你必须过滤掉它。我很确定这是你最好的选择。但是如果我有20多个自定义配置的测试?我需要在公共配置中定义所有这些。这不是很难看吗?编辑我的答案,当你有很多自定义配置谢谢,这是最好的解决方案!