首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多配置弹簧引导测试

多配置弹簧引导测试
EN

Stack Overflow用户
提问于 2018-12-08 17:35:08
回答 3查看 8.1K关注 0票数 4

在我的SpringBoot2.1项目中,对于不同的测试(ConfigurationA和ConfigurationB),我有不同的ConfigurationB,它们驻留在不同的包中。这两种配置都定义了相同的bean集,但以不同的方式定义(模拟的与真实的)

正如我知道SpringBoot2.1中引入的Bean覆盖机制一样,我已经设置了属性:spring.main.allow-bean-definition-overriding=true

但是,下面的配置和测试类的设置确实有一个测试。首先,生产部分中有一个@Configuration (我正在使用Maven):

代码语言:javascript
复制
package com.stackoverflow;

@Configuration
public class ProdConfiguration{
...
}

然后,在测试分支中有一个在相同包级别上的通用测试@Configuration

代码语言:javascript
复制
package com.stackoverflow

@Configuration
public class TestConfiguration {
  @Bean
  public GameMap gameMap() {
    return Mockito.mock(GameMap.class);
  }
}

在一个子包中,我有另一个@Configuration

代码语言:javascript
复制
package com.stackoverflow.impl;

@Configuration
public class RealMapTestConfiguration {
  @Bean
  public GameMap gameMap() {
    return new GameMap("testMap.json");
  }
}

当然,还有一个困扰着我的考验:

代码语言:javascript
复制
package com.stackoverflow.impl;

@ExtendWith(SpringExtension.class)
@SpringBootTest
@ContextConfiguration(classes={RealMapTestConfiguration.class, ProdConfiguration.class})
@ActiveProfiles("bug") // spring.main.allow-bean-definition-overriding=true
public class MapImageServiceIT {
  @Autowired
  private GameMap map;
} 

事实证明,注入到我的测试中的GameMap是来自TestConfiguration的模拟实例,而不是来自RealMapTestConfiguration的真实实例。在我的测试中,我有来自ProdConfigurationTestConfiguration的配置,当我想要ProdConfigurationRealMapTestConfiguration时。由于ProdConfiguration*TestConfiguration中定义的bean是不同的,所以组合工作,但是TestConfigurationRealMapTestConfiguration定义了相同的but。TestConfiguration似乎是通过组件扫描获得的,因为它与ProdConfiguration在同一个包中。我的印象是,当重写bean时,更倾向于使用更接近测试类的bean定义。然而,情况似乎并非如此。

以下是我的问题:

  1. 当重写bean时,订单是什么?哪个豆子胜过哪一个?
  2. 如何在我的测试中获得正确的实例(使用不同的bean名称不是一个选项,因为在实际中,注入bean不是直接用于测试,而是在测试使用的服务中,并且没有限定符)。
EN

回答 3

Stack Overflow用户

发布于 2018-12-08 21:02:58

我没有使用spring.main.allow-bean-definition-overriding=true属性,但是在测试类中指定特定的配置对我来说很好,可以作为在不同测试中切换对象的一种方式。

你说..。

事实证明,注入到我的测试中的GameMap是来自TestConfiguration的模拟实例,而不是来自RealMapTestConfiguration的真实实例。

但是RealMapTestConfiguration确实返回了一个模拟

代码语言:javascript
复制
package com.stackoverflow.impl;

@Configuration
public class RealMapTestConfiguration {
  @Bean
  public GameMap gameMap() {
    return Mockito.mock(GameMap.class);
  }
}
票数 1
EN

Stack Overflow用户

发布于 2018-12-09 03:33:01

我认为这里的问题是,包含ContextConfiguration会抵消@SpringBootTest的影响。@SpringBootTest的效果是在您的应用程序中寻找@SpringBootConfiguration (我相信从相同的包开始)。但是,如果应用了ContextConfiguration,那么就会从那里加载配置。

另一种说法是:由于测试中有ContextConfiguration,所以禁用了对@Configuration类的扫描,并且没有加载TestConfiguration

我不认为我对您的配置设置有完整的了解,所以这里不能真正推荐最佳实践,但是解决这个问题的一个快速方法是在测试中将TestConfiguration添加到您的ContextConfiguration中。确保最后添加它,以便它覆盖其他两种配置中的bean定义。

另一件可能有效的事情是完全删除@ContextConfiguration并让SpringBootApplication扫描完成它的工作--这就是您所说的最接近的bean定义可能适用的地方。

票数 1
EN

Stack Overflow用户

发布于 2019-11-28 13:58:31

在这种情况下,只需在配置类上不使用@Configuration,然后使用@Import手动将其导入测试,例如:

代码语言:javascript
复制
@SpringBootTest
@Import(MyTest.MyTestConfig.class)
public class MyTest {

    @Autowired
    private String string;

    @Test
    public void myTest() {
        System.out.println(string);
    }

    static class MyTestConfig {
        @Bean
        public String string() {
            return "String";
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53685135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档