【发布时间】:2018-12-10 15:23:06
【问题描述】:
我目前遇到的问题是,在使用 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 文件夹中。
【问题讨论】:
标签: java spring maven junit dependency-injection