春天& JUnit:Spring实例化测试类的两个实例,只为一个实例注入依赖项,运行另一个实例

时间:2014-03-14 23:12:39

标签: java spring junit dependency-injection

我正在尝试做什么:运行一个JUnit测试(一个JUnit测试类使用单个测试方法)。测试类有一个依赖项,我希望Spring在运行测试之前处理(注入)。

我看到的内容:测试类被实例化两次,其中一个实例的依赖性被满足(注入)而另一个实例则不满足。使用依赖项注入的实例运行测试。

我的猜测:我猜测测试类是实例化两次因为Spring使用第一个实例来分析依赖项(可能使用反射来查找注释,我没有使用) 。

但是:我终生无法弄清楚为什么没有创建/注入依赖关系的测试类实例用于运行测试。

的test.xml

<beans ...>
  <bean id="test" class="com.example.MyTestClass">
    <property name="primaryDependency" ref="pridep"/>
  </bean>

  <bean id="pridep" class="com.example.MyPrimaryDependency">
    <property name="dataSource" ref="ds"/>
  </bean>

  <bean id="ds" class="com.mysql.jdbc.jdbc2.optional.MysqlDataSource"/>
</beans>

MyTestClass.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:test.xml"})
public class MyTestClass {

  private IPrimaryDependency  mDep = null;

  public MyTestClass() {
  }

  public void setPrimaryDependency(IPrimaryDependency dep) {
    mDep = dep;
  }

  @Before
  public void createImageData() {
  }

  @Test
  public void testImageSearch() {
    assertNotNull("mDep is null", mDep);
  }
}

MyPrimaryDependency.java

public class MyPrimaryDependency extends RequiresADataSource implements IPrimaryDependency {

  public MyPrimaryDependency() {
  }
}

现有相关问题Spring dependency injection null when running a test case,但我无法辨别该答案会发生什么。

对于新手问题感到抱歉 - 我一直在搜索文档(和打扰同事)好几天,对此感到困惑。

谢谢!

2 个答案:

答案 0 :(得分:2)

添加@Autowired

@Autowired
private IPrimaryDependency mDep;

说明:

JUnit为每个测试创建全新的测试类实例。 Spring JUnit运行器只通过“准备”创建的对象来扩展这种行为,这基本上意味着设置应用程序上下文并注入注释驱动的依赖项。

在您的情况下,测试类被实例化两次:从test.xml(在那里注入属性)和JUnit runner来运行第一个测试方法。 但是当由JUnit创建时,Spring不知道它需要注入一些东西,因为类中没有注释,因此属性最终为null。

有关实施细节,请参阅SpringJUnit4ClassRunnerDependencyInjectionTestExecutionListener的源代码。

答案 1 :(得分:1)

您的测试类是

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:test.xml"})
public class MyTestClass {

您使用JUnit运行此类。由于@RunWith,JUnit使用SpringJUnit4ClassRunner的实例来实例化类并运行其测试。

由于@ContextConfigurationClassRunner会通过加载ApplicationContext文件生成test.xml

test.xml个文件的测试类定义为<bean>

<bean id="test" class="com.example.MyTestClass">
    <property name="primaryDependency" ref="pridep"/>
</bean>

所以Spring也会生成一个实例并设置相应的属性。


基本上,我所得到的是你的测试类不应该是Spring上下文中的bean。创建一个不同的测试类并注入具有注入目标的bean并将其注入到测试类中。