0

私は最近、次のようなクラスに出くわしました。

public class SomeDao {
   @Inject
   private DataSource dataSource;

   @Value("#{someMap['someDao.sql']}")
   private String sql;

   private JdbcTemplate jdbcTemplate;

   @PostConstruct
   private void postConstruct() {
      jdbcTemplate = new JdbcTemplate(dataSource);
   }

   ...
}

ここで、DataSource と SQL 文字列を挿入して、このクラスを単体テストしたいと思います。私が見る限り、これには 2 つのオプションがあります。

  1. 遅くなるアプリケーションコンテキストをロードし、テストに必要のないものを大量にロードする可能性が最も高い
  2. リフレクションを使用してプライベート プロパティを設定し、プライベート postConstruct() メソッドを呼び出します

春のアノテーションの前の時代には、クラスは次のように書かれていました:

public class SomeDao {
   private String sql;
   private JdbcTemplate jdbcTemplate;

   public SomeDao(DataSource dataSource, String sql) {
      this.jdbcTemplate = new JdbcTemplate(dataSource);
      this.sql = sql;
   }    
   ...
}

そして、リフレクションやスプリングを必要とせずに、このクラスを簡単にテストできたはずです。私のクラスは純粋な pojo であり、Spring の依存関係はありませんでした。

では、スプリング アノテーションは良いものですか、それとも一歩後退しているのでしょうか? それらを使用する必要がある場合と、古い XML アプリ コンテキストを使用する必要がある場合はありますか?

ありがとう、ランス。

4

4 に答える 4

4

Bean のモックでテスト コンテキストを宣言し、そこからクラスに必要なものを注入してみませんか? それは人々が通常行うことであり、非常に簡単です。

@Configurationこれを行う最も軽量な方法は、モックを提供するメソッドを持つアノテーションが付けられた、テスト クラス内に内部クラスを提供することです。

@Configuration
public class DataAccessConfiguration {

    @Bean
    public DataSource dataSource() {
        DataSource dataSource =  mock(Datasource.class);
        return dataSource;
    }

    @Bean
    public Map<String,String> someMap() {
        Map<String, String> map = new HashMap<>();
        map.put("someDao.sql", "somevalue");
        return map;
    }

}

そのため、自動配線をあきらめる代わりに、実際にそれを利用できます。また、ロードされたコンテキストを、テスト中のクラスが必要とするものだけに制限します。

于 2012-05-03T15:56:33.657 に答える
3

必要な依存関係であっても、コンストラクター注入よりもセッター注入 (またはprivateフィールドへの注入) を好む不健康な傾向があると思います。

この例では両方の依存関係が必要であるため、次のように書き直すことができます。

public class SomeDao {
    private String sql;
    private JdbcTemplate jdbcTemplate;

    @Inject  
    public SomeDao(
        DataSource dataSource, 
        @Value("#{someMap['someDao.sql']}") String sql) {

        this.jdbcTemplate = new JdbcTemplate(dataSource);
        this.sql = sql;
    }   
    ...
}

したがって、これは Spring アノテーションの問題ではなく、それらの不適切な使用の問題です。

于 2012-05-03T15:59:49.387 に答える
0

私は axtavt の答えに同意しますが、簡単な回避策はReflectionTestUtils、スプリング テスト アーティファクトのクラスを使用することです。このようなシナリオに便利なワンライナーを提供します。

ReflectionTestUtils.setField(dao, "dataSource", mydataSource);

単体テストの場合、これは非常に簡単です。

見るReflectionTestUtils

于 2012-05-03T16:11:15.583 に答える
0

セッターとコンストラクターで引き続き注釈を使用できます。これは、依存関係がより明確になるため、私が個人的に好むものです。これらの 50 個のパラメーター コンストラクターは本当に際立っています。

于 2012-05-03T15:46:48.210 に答える