我有一个抽象类:
@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哪个类 - 实现一个接口或扩展一个Abstract类 - 你希望使用它。但那不是我的情况。我想使用抽象类本身。
我也尝试过使用@Resource,如下所示:
public class BaseReportTest extends BaseTest {
@Resource(name = "baseReport")
BaseReport _report;
Spring告诉我没有这个名字的豆子。 :(
我该怎么做?
干杯。
答案 0 :(得分:16)
抽象类无法实例化,您需要使用具体的实现。 与常规java相同,如果您尝试实例化一个抽象类,它会告诉您在其中实现抽象方法。执行此操作时,将创建一个匿名类。它不是抽象类的实例,而是抽象类的新子类。
Spring将查找扩展基类的类,即Report1和Report2, Spring看到它有多个符合要求的类,并且不知道选择哪一个。因此,您会收到有多个匹配bean的错误。
你可以通过制作一个"适配器"来解决这个问题。基本上创建一个扩展基类的具体类,实现抽象方法,但不做任何事情。然后,您可以自动装配该实现并对其进行测试。但是,由于您正在测试报告1和2,因此您的抽象类应该已经过测试。如果您的基类仍然出现错误,则表示您不使用的逻辑导致错误,这无论如何都是不好的做法。还有一个测试工具,你可以用这种方式发现未使用的代码。