1

タイトルが誤解を招く可能性のある質問をしたので、詳細な内容でもう一度質問を試みます。(質問が長いようですが、ご容赦ください)

私がやろうとしていること:DAOのテストケースを書いて、それを機能させたいだけです。コンテナ(アプリサーバー)内でDAOが正常に機能することはわかっていますが、テストケースからDAOを呼び出すと機能しません。コンテナの外にあるからだと思います。

私のspring-for-iBatis.xmlのもの

<bean id="IbatisDataSourceOracle" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/RSRC/my/db/oltp"/>
</bean>
<bean id="MapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
  <property name="configLocation" value="classpath:sql-map-config-oracle.xml"/>
  <property name="dataSource" ref="IbatisDataSourceOracle"/>
 </bean>

私のsql-map-config-oracle.xmlのもの

<sqlMapConfig>
   <settings enhancementEnabled="true" useStatementNamespaces="true" />
 <transactionManager type="JDBC">
  <dataSource type="JNDI">
   <property name="DataSource" value="jdbc/RSRC/my/db/oltp"/>
  </dataSource>
 </transactionManager>
         <sqlMap resource="mymapping.xml"/>
</sqlMapConfig>

私の抽象クラス:

public abstract MyAbstract {
    public SqlMapClientTemplate getSqlTempl() SQLException{
        public static final String ORCL = "jdbc/RSRC/PIH/eiv/oltp";
        try {
            ApplicationInitializer.getApplicationContext().getBean("MapClient");
            SqlMapClient scl = (SqlMapClient) ApplicationInitializer.getApplicationContext().getBean("MapClient");
            DataSource dsc = (DataSource) MyServiceLocator.getInstance().getDataSource(ORCL);
            return new SqlMapClientTemplate (dsc, scl);
        }
        catch (NamingException e)
        {
            log.error(ne.getMessage(), e);
            throw new SQLException("some error here: " + e.getMessage());
        }
    } 
}

私のDAO:

public class MyDAO extends MyAbstract{
 public AnObject getSomething(String id)
        {
        HashMap myMap = new HashMap();
        myMap.put("id", id);
        try {
            setSqlMapClientTemplate(getSqlTempl());
        }
        catch (SQLException ne)
        {
            log.error (ne.getMessage(), ne);
        }
        getSqlMapClientTemplate().queryForList("mymapping.someproc", myMap);
        return AnObject ((List)myMap.get("firstresult").get(0));
        }
}

Mytests

public class MyDAOTests extends TestCase {

 public void testMyDAO ()
 {
  MyDAO myd = new MyDAO();
  AnObject ano = myd.getSomething("15");
  assertEquals("1500", ano.getContentId());

 }
}

このコードスニペットで問題全体を提示しようとしました。データベースへの接続を取得できないため、テストは失敗します...コンテナの外部にあるためです。依存性注入をより有効に活用するために設計を修正できることを私は知っています。このスニペットに基づいて、テストが機能するようにどのような改善を行うことができるかを教えていただけますか?

私はこれに苦労してきました、そして本当にいくつかの助けをいただければ幸いです。

PS:setSqlMapClientTemplate()DAOへの呼び出しを単純MyDAO myd = new MyDAO() にしたいので、使用する必要がありました。DAOごとにインターフェイスを作成したくありません。

4

1 に答える 1

6

ここにはたくさんの問題があります。

まず、小さな例でJNDIルックアップ文字列の3つの引用を数えます。DRYは、可能であれば、一度書いて参照するように指示します。

第二に、私はあなたのDAOにあまり感謝していません。これは本当にあなたが書いているものですか、それとも単なる例ですか?これは春のイディオムではないと思います。インターフェースはありません。宣言型トランザクションを1つなしでどのように実行しますか?iBatisのSpringドキュメントをもっと注意深く見ることをお勧めします。

第三に、JUnit 4.4を使用することをお勧めします。さらに良いのは、TestNGイディオムであるアノテーションを使用することです。また、Spring @ContextConfigurationをチェックして、setUpに必要なBeanを注入します。

第4に、JNDIルックアップサービスを実行する必要があるため、DAOは機能しません。また、コンテナーなしではDAOを取得できません。答えは、テスト用のDriverManagerデータソースを用意することです。

更新:試してみるアイデアは次のとおりです。iBatisにはSpringイディオムを使用してください。レガシーによってこれができない場合は、おそらくSpringが答えではありません。

これを実行したら、データソースアプリのコンテキストをオーバーライドして、テストにJNDIの代わりにDriverManagerを使用するだけです。

于 2009-11-10T02:50:56.770 に答える