代码之家  ›  专栏  ›  技术社区  ›  hotzst

具有多个配置的Spring引导测试

  •  1
  • hotzst  · 技术社区  · 7 年前

    @Configuration 用于驻留在不同包中的不同测试(配置A和配置B)。两种配置都定义了相同的bean集,但方式不同(模拟的与真实的)

    据我所知 Bean overriding Spring Boot 2.1中引入的机制,我设置了以下属性: spring.main.allow-bean-definition-overriding=true .

    @配置 在生产部分(我使用Maven):

    package com.stackoverflow;
    
    @Configuration
    public class ProdConfiguration{
    ...
    }
    

    @配置 在相同的包级别上:

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

    @配置 :

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

    当然,还有一个测试让我感到不安:

    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 . 最近在我的测试中,我从 ProdConfiguration 测试配置 ,当我想 RealMapTestConfiguration 产品配置 *TestConfiguration 测试配置 RealMapTestConfiguration 定义相同的定义。看起来像是 测试配置 通过组件扫描获取,因为它与 产品配置 我的印象是,当重写bean时,更接近测试类的bean定义将是首选。然而,情况似乎并非如此。

    1. 重写bean时,顺序是什么?哪个bean覆盖哪个bean?
    2. 如何在我的测试中获得正确的实例(使用不同的bean名称不是一个选项,因为实际上注入的bean不是直接在测试中使用的,而是在测试使用的服务中使用的,并且没有限定符)
    2 回复  |  直到 7 年前
        1
  •  1
  •   pcoates    7 年前

    我还没用过这个 spring.main.allow-bean-definition-overriding=true

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

    但是RealMapTestConfiguration确实返回一个mock

    package com.stackoverflow.impl;
    
    @Configuration
    public class RealMapTestConfiguration {
      @Bean
      public GameMap gameMap() {
        return Mockito.mock(GameMap.class);
      }
    }
    
        2
  •  1
  •   akhaku kentaro    7 年前

    我认为这里的问题是包括 ContextConfiguration 使…的(部分)效果无效 @SpringBootTest . @春靴测试 有寻找的效果 @SpringBootConfiguration 上下文配置 应用,然后从那里加载配置。

    另一种说法是:因为你 @Configuration TestConfiguration 未加载。

    我不认为我对您的配置设置有一个完整的了解,因此不能在此推荐最佳做法,但解决此问题的一个快速方法是添加 给你 上下文配置 在你的测试中。确保最后添加它,以便它覆盖其他两个配置中的bean定义。

    另一件事 工作正在进行中 @ContextConfiguration SpringBootApplication 扫描做它的事情——这就是你所说的最接近bean定义的地方。

        3
  •  0
  •   rgrebski    6 年前

    在这种情况下,不要在配置类上使用@Configuration,而是使用@import手动将其导入测试,例如:

    @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";
            }
        }
    }