2

単体テストにはH2データベースを使用しています。私のアプリケーションでは、FooXml次のように定義されたと呼ばれるエンティティオブジェクトがあります。

@Entity
@Table(name = "T_FOOXML")
@SequenceGenerator(allocationSize = 1, name = "S_FOOXML", sequenceName = "S_FOOXML")
@NamedQueries( ... )
@Cache(usage = CacheConcurrencyStrategy.NONE)
public class FooXml implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "S_FOOXML")
    @Column(name = "FOOXML_ID")
    private Integer id;

    @Type(type = "my.app.common.HibernateXMLType")
    @Column(name = "FOOXML_CONTENT")
    @Basic(fetch = FetchType.LAZY)
    private String xmlContent;

    ...

}

したがって、データベースからXMLコンテンツを読み書きするためにmy.app.common.HibernateXMLType、を実装する独自のXMLTypeを作成しましたorg.hibernate.usertype.UserType。メソッドnullSafeSetnullSafeGetはそこで定義されています。

ここで、テストにH2インメモリデータベースを使用したいと思います。一部のテストでは、このFooXmlクラスを使用しています。H2はOracleをサポートしていないためXmlType、をカスタマイズする必要がありますmy.app.common.HibernateXMLType。たとえば、その部分を追加しました。

public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
    ...
    // Case where H2 Database is used as the dataSource...
    if (st.getConnection() instanceof org.h2.jdbc.JdbcConnection) {
        // Set the XML as a String...
        st.setObject(index, (String) value);
    } else {
        // Case of "normal" behavior (outside tests context)
        ...
    }
}

このアプローチにはいくつかの懸念があります。

  • アプリケーションの本番コードに(つまり、テストコードではなく)テスト目的に直接リンクされているコードを追加します。
  • このクラスはにorg.h2.jdbc.JdbcConnection依存しているため、WARパッケージにh2データベースの依存関係を追加する必要があります。

質問

  • それは私の問題を解決するための最良のアプローチですか、それともそれを行うためのより良い方法がありますか?
  • テスト目的で(my.app.common.HibernateXMLTypeForH2の代わりに)別のタイプを使用するようにHibernateに指示する方法はありますか?my.app.common.HibernateXMLType

ps:H2データベースにテーブルを作成するためのスクリプトは次のとおりです。

create table T_FOO_XML (
    FOOXML_ID NUMBER(9, 0) not null,
    FOOXML_CONTENT CLOB(400000)
);

技術的な詳細:H2データベースv1.3.153、JUnit 4.8.1、Java 1.6、Hibernate 3.2.2、Oracle10gはテストなしの環境で使用されます。

4

2 に答える 2

3

本番コードにテスト目的に直結するコードを追加していきます...

ある意味では、そうです。テストに H2 を使用しているからです。ただし、アプリケーションをよりデータベースに依存しないようにすると主張することができ、H2 をテストのみに使用するのは単なる偶然です。後で、製品の試用版に同梱されているデータベースとして H2 を使用できます。または、後で Oracle と H2 に加えて他のデータベースをサポートすることもできます。

h2 データベースの依存関係

コンパイル時の H2 への依存を回避するには、次を使用できます。

String url = st.getConnection().getMetaData().getURL();
boolean isH2 = url.startsWith("jdbc:h2:");
if (isH2) {
    ...
}

たとえば、他の方法がありますgetMetaData().getDatabaseProductName().equals("H2")-基本的に、クラスオブジェクトではなく文字列と比較します。もちろん、それはコンパイル時に安全ではありません。一方、H2 は将来別の接続クラスを返す可能性があるため、JdbcConnection不安定でもあります。

于 2011-04-28T07:15:55.623 に答える