9

我有一个抽象类:

@Component
public abstract class BaseReport {

  public void export() {
   ...
}

还有一堆扩展它的类,并覆盖 export() 方法(或不覆盖)。

@Component
public final class Report1 extends BaseReport

@Component
public final class Report2 extends BaseReport

我的大多数测试都自动装配扩展 BaseReport 的具体类,没有问题:

public class Report1Test extends BaseTest {

    @Autowired
    Report1 _report;

public class Report2Test extends BaseTest {

    @Autowired
    Report2 _report;

这适用于所有扩展BaseReport 的类的自动装配。但我还需要自动装配抽象类 BaseReport 来测试 export() 方法。

public class BaseReportTest extends BaseTest {

  @Autowired
  BaseReport _report;

当我尝试运行它时,我得到了臭名昭著的:

未定义 BaseReport 类型的唯一 bean:预期单个匹配 bean,但找到 2 [Report1,Report2]。

我试过使用@Qualifier,但@Qualifier 的问题是(据我所知)你用它来告诉Spring你希望使用哪个类——实现接口或扩展抽象类。但这不是我的情况。我想使用抽象类本身。

我也尝试过使用@Resource,如下所示:

public class BaseReportTest extends BaseTest {

  @Resource(name = "baseReport")
  BaseReport _report;

Spring告诉我没有这个名字的bean。:(

我怎样才能做到这一点?

干杯。

4

1 回答 1

17

抽象类不能实例化,需要使用具体的实现。与普通 java 一样,如果您尝试实例化一个抽象类,它会告诉您在其中实现抽象方法。当您这样做时,将创建一个匿名类。它不是抽象类的实例化,而是该抽象类的新子类。

Spring 将寻找扩展您的基类的类,即 Report1 和 Report2,Spring 看到它有多个符合要求的类,但不知道该选择哪一个。因此你会得到有多个匹配 bean 的错误。

您可以通过使“适配器”基本上创建一个具体类来解决此问题,该类扩展您的基类,实现抽象方法,但不做任何事情。然后您可以自动装配该实现并对其进行测试。但是,由于您正在测试报告 1 和 2,因此您的抽象类应该已经过测试。如果您的基类仍然出现错误,则意味着您不使用的逻辑会导致错误,这无论如何都是一种不好的做法。还使用测试覆盖工具,您可以通过这种方式发现未使用的代码。

于 2013-04-12T12:27:49.047 回答