簡體   English   中英

具有多種配置的 Spring Boot 測試

[英]Spring boot test with multiple configuration

在我的 Spring boot 2.1 項目中,我有不同的@Configuration用於不同的測試(ConfigurationA 和 ConfigurationB),它們駐留在不同的包中。 兩種配置都定義了相同的 bean 集,但方式不同(模擬與真實)

由於我知道 Spring Boot 2.1 中引入的Bean 覆蓋機制,因此我設置了屬性: spring.main.allow-bean-definition-overriding=true

但是,我確實對以下配置和測試類的設置進行了測試。 首先在生產部分有一個@Configuration (我使用的是 Maven):

package com.stackoverflow;

@Configuration
public class ProdConfiguration{
...
}

然后在 test 分支中,在同一包級別上有一個通用的 Test @Configuration

package com.stackoverflow

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

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

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的真實RealMapTestConfiguration Aparrently 在我的測試中,當我想要ProdConfigurationRealMapTestConfiguration時,我有ProdConfigurationTestConfiguration的配置。 由於ProdConfiguration*TestConfiguration中定義的 beans 不同,組合工作,但TestConfigurationRealMapTestConfiguration定義相同。 似乎TestConfiguration是通過組件掃描獲取的,因為它與ProdConfiguration位於同一包中。 我的印象是,當覆蓋 bean 時,更接近測試類的 bean 定義將是首選。 然而,情況似乎並非如此。

所以這里是我的問題:

  1. 覆蓋 bean 時,順序是什么? 哪個 bean 覆蓋了哪個 bean?
  2. 如何在我的測試中獲得正確的實例(使用不同的 bean 名稱不是一種選擇,因為實際上注入的 bean 不是直接在測試中使用,而是在測試使用的服務中使用,並且上面沒有限定符.)

我沒有使用spring.main.allow-bean-definition-overriding=true屬性,但是在測試類中指定特定配置作為在不同測試中切換對象的一種方式對我來說效果很好。

你說...

事實證明,注入到我的測試中的 GameMap 是來自 TestConfiguration 的模擬實例,而不是來自 RealMapTestConfiguration 的真實實例。

但是 RealMapTestConfiguration 確實返回了一個模擬

package com.stackoverflow.impl;

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

我認為這里的問題是包含ContextConfiguration @SpringBootTest (部分) @SpringBootTest的效果@SpringBootTest @SpringBootTest有尋找效應@SpringBootConfiguration在您的應用程序(從同一個包開始,我相信)。 但是,如果應用了ContextConfiguration ,則從那里加載配置。

另一種說法是:因為您的測試中有ContextConfiguration ,所以禁用了對@Configuration類的掃描,並且不會加載TestConfiguration

我不認為我對您的配置設置有一個完整的了解,所以在這里不能真正推薦最佳實踐,但解決這個問題的快速方法是在您的測試中將TestConfiguration添加到您的ContextConfiguration 確保最后添加它,以便它覆蓋其他兩個配置中的 bean 定義。

另一件事可能是完全刪除@ContextConfiguration並讓SpringBootApplication掃描完成它的工作 - 這就是您所說的最接近的 bean 定義可能適用的地方。

在這種情況下,不要在配置類上使用 @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";
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM