簡體   English   中英

JUnit + Spring:測試失敗時的依賴注入-CannotLoadBeanClassException

[英]JUnit + Spring: Dependency Injection when testing fails - CannotLoadBeanClassException

我目前遇到的問題是,在使用 JUnit 進行單元測試時,無法找到通過 ClassPathXmlApplicationContext 注入的依賴項。 為了測試整個過程,我正在運行 Maven 測試。 正常運行應用程序時,一切正常,每個依賴項都得到解決。 一旦使用這種類型的依賴注入,問題就會開始出現。

不使用這種類型的依賴注入的其他軟件模塊的單元測試也沒有任何問題。 在我的例子中,一個模塊是一個 maven 項目(沒有 maven 模塊),它引用其他較低級別的 maven 項目。 (例如,一個 maven 項目包含邏輯,另一個包含第一個引用的應用程序的所有相關數據庫模型等)

為了更容易地解決這個問題,我在一個更小規模的項目中重新創建了它,我現在將描述它。

我的小規模架構由三個模塊(Maven 項目)組成:

  • 包含將被注入的類的模塊(用戶)
  • 被測試並拋出異常的模塊。 (junittest)
  • 包含將被注入的類的接口的模塊。 其他兩個模塊都在各自的 pom.xml 中引用了這個模塊。

重要的是要注意第二個模塊“junittest”在它的 pom.xml 中沒有“user”作為直接依賴項。 這需要保持這種方式以防止循環依賴。

現在相關的類和xml文件:

模塊“junittest” - 要測試的類

每當 junit 測試調用 useExternalInjectedDependency() 方法時,都會拋出異常(您可以在我的帖子下方看到)。

public class ToBeTested {
    private final String CONTEXT_FILENAME = "tobetestedContext.xml";

    private final String USERMANAGER_BEAN_ID = "userManager";

    private IUserManager userManager;

    public void useExternalInjectedDependency() {
        if (this.userManager == null) {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(CONTEXT_FILENAME);
            this.userManager = context.getBean(USERMANAGER_BEAN_ID, IUserManager.class);
            context.close();
        }
    }
}

模塊“junittest”——依賴注入的上下文文件

<?xml version="1.0" encoding="UTF-8"?>
...
<!-- GET USERMANAGER BY DEPENDENCY INJECTION -->
<bean id="userManager" class="com.project.modules.user.UserManager">
</bean>

模塊“junittest” - pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>test.test</groupId>
    <artifactId>junittest</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <main.basedir>${basedir}/../..</main.basedir>
        <maven.compiler.source>9</maven.compiler.source>
        <maven.compiler.target>9</maven.compiler.target>
        <java.version>9</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.project.modules</groupId>
            <artifactId>defaultmodels</artifactId>
            <version>[0.0.1-SNAPSHOT,)</version>
        </dependency>

        <!-- Spring dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.0.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.0.3.RELEASE</version>
        </dependency>

        <!-- Dependencies for testing -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <!-- Include Maven Surefire for Unit testing -->
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.0</version>
                    <configuration>
                        <argLine>-Djdk.attach.allowAttachSelf</argLine>
                        <includes>
                            <include>**/*Test.java</include>
                        </includes>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

我得到的錯誤

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running junittest.ToBeTestedTest
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.938 s <<< FAILURE! - in junittest.ToBeTestedTest
[ERROR] testDependencyInjectionViaContext(junittest.ToBeTestedTest)  Time elapsed: 0.87 s  <<< ERROR!
org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.project.modules.user.UserManager] for bean with name 'userManager' defined in class path resource [tobetestedContext.xml]; nested exception is java.lang.ClassNotFoundException: com.project.modules.user.UserManager
    at junittest.ToBeTestedTest.testDependencyInjectionViaContext(ToBeTestedTest.java:10)
Caused by: java.lang.ClassNotFoundException: com.project.modules.user.UserManager
    at junittest.ToBeTestedTest.testDependencyInjectionViaContext(ToBeTestedTest.java:10)

我能做些什么來解決這個問題並解決依賴關系? 如果需要,我很樂意提供有關問題和我的應用程序的更多信息。


更新

所以我有點找到了解決我的問題的方法。 雖然不是很干凈,但它現在確實有效。 對於任何感興趣的人:我基本上為無法正確注入的接口創建了虛擬實現並將它們放在 src/test/java 中。 除了接口所需的實現方法之外,它們不包含真正的源代碼,它們實現了。 我還創建了一個新的 context.xml,其中包含現在本地實現(虛擬實現)的路徑,並將其放在 src/test/resources 文件夾中。

嘗試這個:

ApplicationContext context = new ClassPathXmlApplicationContext(CONTEXT_FILENAME);

或者

ApplicationContext context = new ClassPathXmlApplicationContext("file:src/main/resources/beans.xml");

file:前綴指向文件系統資源,而不是類路徑。

暫無
暫無

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

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