web-dev-qa-db-ja.com

ResultSetをパラメーターとして受け取るメソッドの単体テスト

インスタンス化できないオブジェクトを単体テストする方法を教えてください。現在、ResultSetをオブジェクトに変換するメソッドがありますが、これがプログラミングの原則に違反しているかどうかはわかりません。

public CItem convert(ResultSet rs) {
    CItem ci = new CItem ();

    try {
        ci.setHinumber(rs.getString("id"));
        ci.setHostname(rs.getString("sysname"));
        ci.setOs(rs.getString("zos"));
        ci.setTenant(rs.getString("customer_name"));
        //ci.setInstallation(rs.getField("installation_name"));
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return ci;
}

単体テストができないという理由だけでこれに取り組む別の方法を探す必要がありますか?または、どういうわけかResultSetオブジェクトを偽造できますか?.

任意の助けいただければ幸いです。

14
Laurens

単純にResultSetをモックして各フィールドに値を提供し、結果に期待どおりの結果が含まれていることを確認できます。

たとえば、 Mockito の場合、テストは次のようになります。

@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {

    @Mock
    private ResultSet resultSet;

    @Test
    public void testConvert() throws SQLException {
        // Define the behavior of the mock for each getString method's call
        Mockito.when(resultSet.getString("id")).thenReturn("myId");
        Mockito.when(resultSet.getString("sysname")).thenReturn("myHost");
        Mockito.when(resultSet.getString("zos")).thenReturn("myOS");
        Mockito.when(resultSet.getString("customer_name")).thenReturn("myCustomerName");

        // Launch the method against your mock
        SomeClass someClass = new SomeClass();
        CItem item = someClass.convert(resultSet);

        // Check the result
        Assert.assertNotNull(item);
        Assert.assertEquals("myId", item.getHinumber());
        Assert.assertEquals("myHost", item.getHostname());
        Assert.assertEquals("myOS", item.getOs());
        Assert.assertEquals("myCustomerName", item.getTenant());
    }
}
15
Nicolas Filotto

クラスがDBアクセスを処理しない場合、ResultSetを引数として受け入れると、コードのにおいのように感じられます。

MockitoやPower Mockなどのモックフレームワークを使用して、モックResultSetを作成できます。ただし、作成していないクラス(つまり、ライブラリ/ JDKクラス)をモックしないでください。

ResultSetがOrderテーブルのいくつかの注文データを表すとします。この方法が本当に必要とするのは「注文データ」であり、この時点でこのデータをどこからどのように取得するかについて心配する必要はありません。したがって、このようなインターフェースを理想的に定義する必要があります。

interface OrderRepository {
    OrderData get();
}

次に、ResultSetを処理するこのインターフェースJDBCOrderRepositoryを実装するクラスを作成できます。そして、メソッド( 'convert')がResultSetではなくOrderRepositoryを受け入れるようになります。メソッドをテストするために、簡単なResultSetではなくOrderRepositoryをモックします。

では、JDBCOrderRepositoryをどのようにテストしますか?おそらく、実際には統合テストであるDBの実行中のインスタンスでテストする必要があります。

1
Fahim Farook