簡體   English   中英

如何使用 spring 引導和注釋在測試 class 中正確注入 Bean

[英]How to inject Beans inside a test class properly with spring boot and annotations

我有一個 class 我想在某個配置文件處於活動狀態時測試它是否使用正確的 Bean。 因此,我編寫了一個測試 class,配置文件處於活動狀態,用於國內服務(它又使用園藝服務和清潔服務,所有這些都是自動裝配的)。

@Component
public class HumanDomesticService implements DomesticService {
    private CleaningService cleaningService;
    private GardeningService gardeningService;
    private Logger logger;

    HumanDomesticService() {
    }

    @Autowired
    public HumanDomesticService(CleaningService cleaningService, GardeningService gardeningService, Logger logger) {
        setCleaningService(cleaningService);
        setGardeningService(gardeningService);
        setLogger(logger);
    }

我做了一個測試配置 class,它應該掃描整個項目的 Bean,因為 SpringBootApplication 注釋包含 ComponentScan 注釋。

@SpringBootApplication
public class ActiveProfileConfig {
}

然而我的測試 class 似乎找不到合適的 Bean 來完成測試。

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'be.mycompany.springlessons.housekeeping.domestic.service.ActiveProfileSmallHouseTest': Unsatisfied dependency expressed through field 'service'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'be.mycompany.springlessons.housekeeping.domestic.service.DomesticService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

之后,我嘗試在我的配置 class 中制作 Bean,這使我的測試成功,但隨后 Maven 抱怨找到 2 個可以注入那里的 Bean。 Maven 似乎可以通過 ComponentScan 看到所有的 bean。

最后,我結束了對我的測試和 Maven 的必要類的導入,但它似乎不是正確和最佳的解決方案。

@SpringBootTest(classes = ActiveProfileConfig.class)
@ActiveProfiles(profiles = "smallHouse")
@Import({HumanDomesticService.class, HumanCleaningService.class, RobotCleaningService.class, HumanGardeningService.class, HedgeTrimmerFactory.class, Broom.class, VacuumCleaner.class,
        Sponge.class, DisposableDuster.class, LawnMower.class, LoggerFactory.class})
public class ActiveProfileSmallHouseTest {
    @Autowired
    private DomesticService service;

我試圖在互聯網上搜索另一種解決方案,發現我不是唯一一個有問題的人,但似乎還沒有其他解決方案有效。

ComponentScan 在測試 class 中似乎不起作用的原因是什么?如何最好地解決這個問題?

很長一段時間以來,我一直遇到完全相同的問題。 通過添加我想使用的主要配置,我能夠在 Spring Boot 中解決這個問題。 以及我的測試對@SpringBootTest注釋的 classes 字段的所有必需依賴項(所有 AutoWires)。

@SpringBootTest(classes = {ActiveProfile.class, HumanDomesticService.class, HumanCleaningService.class, RobotCleaningService.class, HumanGardeningService.class, HedgeTrimmerFactory.class, Broom.class, VacuumCleaner.class,
    Sponge.class, DisposableDuster.class, LawnMower.class, LoggerFactory.class})
@ActiveProfiles({"smallhouse"})
public class ActiveProfileSmallHouseTest {
    @Autowired
    private DomesticService service;
...
}

如果您沒有使用 Spring 引導。 您可以使用@ContextConfiguration注釋解決此問題。 它以相同的方式工作,並且也是@SpringBootTest注釋的一部分。

這也是我的主要學習資源中的做法:Pro Spring 5 - Iuliana Cosmina et al - Apress(第 631 頁)

我仍然不知道為什么 ComponentScan 或上下文的自動加載不起作用。 但至少我知道這樣我的測試將始終運行。 此外,您可以只運行使該測試成功所需的類,而無需為測試啟動整個上下文。

我想分享我們對此的最終解決方案。

我們都使用 IntelliJ IDEA 作為 IDE。 在此 IDE 中,我們沒有指定測試不應使用模塊路徑。 IntelliJ 現在有一個設置,可讓您啟用/禁用單元測試模塊路徑的使用。

在 maven 中,我們已經通過將主肯定插件配置為不使用模塊路徑來禁用此功能。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M3</version>
    <configuration>
        <useModulePath>false</useModulePath>
    </configuration>
</plugin>

使用我們 IDEA 中的這個“新”功能,我們還必須禁用它,這樣我們的測試就不會使用 class 路徑。

我們想通了,因為我們的 Maven 階段: mvn test確實運行了測試。

現在所有測試都可以通過@SpringBootTest注解順利運行。

要在 IntelliJ 中進行設置:

  • 在菜單欄中:運行>編輯配置
  • 在左側菜單中打開Templates > JUnit的子菜單
  • 取消選中使用模塊路徑旁邊的復選框
  • 單擊應用>確定

從現在開始,您將運行的所有測試都不會使用此模塊路徑。 如果您已經有現有的測試。 Select 他們贏得了左側的菜單,並取消選中所有他們的使用模塊路徑選項。

顯示使用模塊路徑選項

暫無
暫無

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

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