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を拡張するすべてのクラスのオートワイヤリングでうまく機能します。しかし、export() メソッドをテストするために、抽象クラス BaseReport 自体をオートワイヤーする必要もあります。

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 をテストしているため、抽象クラスは既にテストする必要があります。基本クラスでエラーが引き続き発生する場合は、使用していないロジックがバグを引き起こしていることを意味します。これはとにかく悪い習慣です。また、test coveage ツールを使用すると、未使用のコードをそのように見つけることができます。

于 2013-04-12T12:27:49.047 に答える