当前位置: 首页 > 知识库问答 >
问题:

对于@SpringBootTest,@TestConfiguration类的导入不执行任何操作,而@ContextConfiguration会按预期重写

董翰池
2023-03-14

考虑以下集成测试注释:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
                properties = "spring.main.allow-bean-definition-overriding=true")
@ContextConfiguration(classes = {WorkerTestConfig.class})
//@Import(value = {WorkerTestConfig.class})
@ActiveProfiles({"dev","test"})
public class NumberServiceITest {

WorkestTestConfig的作用是在集成启动期间覆盖真正的bean/bean集,每当我使用@ContextConfiguration时,真正的bean正在后退,并且使用WorkerTestConfig中的一个,每当我使用@导入时,真正的bean是仍然创建并未通过测试

WorkerTestConfig本身尽可能简单:

@TestConfiguration
public class WorkerTestConfig {

    @Primary
    @Bean
    public ScheduledExecutorService taskExecutor() {
        return DirectExecutorFactory.createSameThreadExecutor();
    }
}

有人能解释一下@SpringBootTest注释的另一个神奇行为吗?如果您重现相同的行为,请确认,这样我就可以发布跟踪器,因为我已经看到人们在SO上使用@SpringBootTest和@SpringBootTest在这里使用@导入,并且在Spring引导文档中没有任何东西禁止它:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-excluding-config

完全不明白发生了什么。

版本:2.1.2.发布

更新:

还试图删除真正的bean,以查看是否只是覆盖问题,但是@Import注释只是死水中的一部分,不起作用-

还试图从@TestConfiguration更改为@Configuration,只是为了它,什么都没有。死去的

更新2:

@导入适用于标准的Spring测试:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {Some.class,
                                 Some2WhichDependsOnWorkerTestConfig.class})

@Import(WorkerTestConfig.class)
@ActiveProfiles("test")
public class SomeOtherTest {

共有1个答案

郑茂勋
2023-03-14

未定义在测试中使用@Import类时处理它们的顺序。测试的@Import特性主要是为了方便注册额外的bean而添加的,并不打算用它来代替bean定义。

如果您想深入研究并确切了解发生了什么,您可以打开ConfigurationClassParser并在doProcessConfigurationClass中添加一个条件断点。添加以下条件代码:

System.err.println(configClass);
return false;

现在,如果调试应用程序,在处理配置类时将获得额外的输出。

使用注释属性而不使用@Import时,您将看到:

ConfigurationClass: beanName 'demoImportBugApplication', com.example.demoimportbug.DemoImportBugApplication
ConfigurationClass: beanName 'original', class path resource [com/example/demoimportbug/first/Original.class]
ConfigurationClass: beanName 'workerConfig', class path resource [com/example/demoimportbug/first/WorkerConfig.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/scheduling/annotation/ProxyAsyncConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/scheduling/annotation/ProxyAsyncConfiguration.class]
ConfigurationClass: beanName 'someTestSecondConfiguration', com.example.demoimportbug.second.SomeTestSecondConfiguration
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/context/PropertyPlaceholderAutoConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/cache/GenericCacheConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/cache/SimpleCacheConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/cache/NoOpCacheConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/context/ConfigurationPropertiesAutoConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/info/ProjectInfoAutoConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/task/TaskSchedulingAutoConfiguration.class]

当您使用不带classes属性的@Import时,您将获得:

ConfigurationClass: beanName 'org.springframework.boot.test.context.ImportsContextCustomizer$ImportsConfiguration', org.springframework.boot.test.context.ImportsContextCustomizer$ImportsConfiguration
ConfigurationClass: beanName 'null', class path resource [com/example/demoimportbug/first/SomeFirstUsingSecondConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [com/example/demoimportbug/second/SomeTestSecondConfiguration.class]
ConfigurationClass: beanName 'demoImportBugApplication', com.example.demoimportbug.DemoImportBugApplication
ConfigurationClass: beanName 'original', class path resource [com/example/demoimportbug/first/Original.class]
ConfigurationClass: beanName 'workerConfig', class path resource [com/example/demoimportbug/first/WorkerConfig.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/scheduling/annotation/ProxyAsyncConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/scheduling/annotation/ProxyAsyncConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/context/PropertyPlaceholderAutoConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/cache/GenericCacheConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/cache/SimpleCacheConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/cache/NoOpCacheConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/context/ConfigurationPropertiesAutoConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/info/ProjectInfoAutoConfiguration.class]
ConfigurationClass: beanName 'null', class path resource [org/springframework/boot/autoconfigure/task/TaskSchedulingAutoConfiguration.class]

第一个版本在SomeTestSecondConfiguration之前加载WorkerConfig,而第二个版本在WorkerConfig之前加载SomeTestSecondConfiguration

您还会注意到,第二个版本有一个重要内容定制器$重要配置类,它触发了额外的导入。

如果您查看SpringBootTestContextBootstrapper,您可以在getOrFindConfigurationClass方法中看到已定义排序,并且您的附加测试类将始终列在主配置之后。

tl;dr如果需要定义顺序,请使用classes属性。如果您想添加额外的bean,并且不想覆盖任何内容,请使用@Import

您可能还想看看@MockBean,它提供了一种更健壮的方法来用mock替换bean。

 类似资料:
  • 我在一个项目中工作,我需要要求用户输入一个路径来使用jOptionPane保存程序,但我的问题是,如果用户没有在文本中添加任何内容,然后单击取消或确定,将得到一个错误...我试图控制它,检查字符串是否为空()或等于空

  • 问题内容: 我有一个带有两列唯一键的表: 我想在该表中插入一行,但是如果键存在,则什么也不做!我不希望因为键存在而产生错误。 我知道有以下语法: 但是是否有类似的东西: ? 问题答案: 是的,使用(即使已分配给自身,它也不会触发行更新)。 如果您不关心错误(转换错误,外键错误)和自动递增字段用尽(即使由于重复键而未插入行,它也会增加),请使用。

  • 我正在尝试通过NIFI从oracle数据库中提取数据。在画布中,我将文件大小为0 KB的“GenerateFlowFile”处理器安排为每5分钟运行一次。这只是为了在成功时触发“executesql”处理器。对于“executeSQL”,我将DB连接池服务设置为DBCPConnectionPool。我输入SQL查询“select*FROM sometable”。我的DBCPConnectionPo

  • 阅读引导文档,您可以看到对齐示例部分。 它告诉您可以使用use flexbox对齐实用工具以引导CSS类的形式垂直和水平对齐列、和,但是当我尝试它时,内容并没有像预期的那样垂直对齐全高,请参见下面的代码: 我希望在的垂直中间有内容,在的底部有内容。 我做错了什么还是误解了什么?

  • 问题内容: 我正在运行一个Electron项目,一切都很好。但是现在,当我运行package.json中的任何脚本(包括npm start)时,它只是转义了一行而没有执行任何操作。 我的package.json: 我尝试更新NPM,但没有用。当我在其他项目中尝试过时,也不起作用。 提前致谢 问题答案: npm具有配置密钥。它的期望值是布尔值,默认设置为。 可能是由于疏忽而将其设置为。 要/ 的配置

  • 我的第一个列表中有3个对象,但只有一个包含必需的注释 两个列表都以包含包含注释的唯一对象结尾 如果有人有主意的话,我就有点迷路了!