JUnit + Spring:测试失败时进行依赖注入-CannotLoadBeanClassException

时间:2018-07-02 11:47:30

标签: java spring maven junit dependency-injection

我目前有一个问题,当用JUnit进行单元测试时,找不到通过ClassPathXmlApplicationContext注入的依赖项。 为了测试整个事情,我正在运行Maven测试。 正常运行应用程序时,一切工作正常,每个依赖关系都得到解决。一旦使用这种类型的依赖注入,问题就会开始显现。

不使用这种类型的依赖注入的其他软件模块的单元测试也可以正常工作。就我而言,模块是一个Maven项目(没有Maven模块),它引用了其他较低级别的Maven项目。 (例如,一个包含逻辑的maven项目和另一个包含逻辑的maven项目,其中包含第一个引用的应用程序的所有相关数据库模型。)

为了更轻松地解决问题,我在一个现在将要描述的规模较小的项目上重新创建了它。

我的小型体系结构由三个模块(Maven项目)组成:

  • 包含将要注入的类的模块(用户)
  • 经过测试并引发Exception的模块。 (junittest)
  • 包含将要注入的类的Interface的模块。其他两个模块都在各自的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文件夹中。

1 个答案:

答案 0 :(得分:0)

尝试一下:

ApplicationContext context =新的ClassPathXmlApplicationContext(CONTEXT_FILENAME);

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

file:preffix指向文件系统资源,而不是类路径。