0

我有一个 Spring 3.1/Java/Tomcat 应用程序。我有一个服务类如下:

public class SomeServiceImpl implements SomeService {

  @Autowired
  public AnotherService anotherService;

  //  other code...

这使用了另一个自动装配的服务类 AnotherService。这两个服务类都在 serviceContext.xml 文件中声明。

我正在编写 junit 来测试 SomeServiceImpl 并使用 autowired 来注入被测类 (SomeService) 以及被测类 (AnotherService) 所需的模拟 (EasyMock) 依赖项。AnotherService 的 easymock 依赖项在 testContext.xml 中定义,如下所示:

    <bean id="mockAnotherService" class="org.easymock.EasyMock" factory-method="createMock" primary="true">
        <constructor-arg value="com.xyz.AnotherService" />
    </bean>

在我的测试类中,我配置为使用两个上下文文件。但是,我看到 ServiceImpl 已正确连接到实际实现(这是所需的),但不是另一个服务的模拟版本,而是创建版本 (AnotherServiceImpl) 正在连接。

如何获取我的依赖项的模拟版本?我不能在实际实现中使用@Resource 或@Qualifier,因为那样会破坏目的。我可以在我的测试课中使用这些。

4

2 回答 2

2

如果它们都在 中声明serviceContext.xml,并且您想模拟其中一个,那么该文件对测试没有用处。要么拆分它,以便您可以使用结合了包含模拟的测试上下文的“真实”Spring上下文文件之一,或者只是手动创建bean并AnotherService使用setter方法设置。控制反转的优点之一是允许您手动创建 bean 并以这种方式注入依赖项。

于 2012-05-11T15:10:09.387 回答
1

您可以将 serviceContext.xml 导入到 testContext.xml 中,然后只在测试用例中引用 textContext.xml,而不是配置为使用这两个上下文文件。

当您将配置文件导入另一个文件时,另一个文件有机会覆盖导入文件中的 bean 定义。

确保模拟的 id 与您的类相同 - 否则它将创建两个不同的 bean。另一个问题是模拟对象没有公布正确的接口类型——因此按类型自动装配可能会失败。要解决该问题,您需要执行以下操作。我将这种方法与 mockito 一起使用 - 也应该适用于简单的模拟。

<bean id="anotherService" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target">
     <bean class="org.easymock.EasyMock" factory-method="createMock" primary="true">
        <constructor-arg value="com.xyz.AnotherService" />
    </bean>
    </property>
    <property name="proxyInterfaces">
      <value>com.xyz.AnotherService</value>
    </property>
  </bean>

要尝试的另一件事是在您的类中创建 Java Config 样式的方法来创建模拟对象。如果直接在测试类中创建它不起作用,您可以使用另一个带有 @Configuration 的类来创建模拟,然后在 testContext.xml 中将其定义为 bean

  @Bean
  AnotherService anotherService() {
      return EasyMock.createMock(AnotherService.class);
  }
于 2012-05-11T15:16:49.937 回答