2016-04-25 48 views
3

私はJUnitを使用して、Postgresデータベースにアクセスするリポジトリをテストしています。Postgresのcurrent_timestampをJUnitテストの定数に設定しますか?

すべてのテストデータは手動で設定されていたので、結果に期待する値が正確にわかっています。 current_timestampを使ってステートメントをテストするのに苦労します。select * from phone_number where current_timestamp <= expires;

問題は私のテストデータが一定ですが、テストの実行ごとに時間が進んでいくということです。

current_timestampに一定の値を返す方法はありますか?もちろん

これは、私は3つの解決策だったいくつかのオプションのいずれか、次のようになります。

  • は私のテストデータで基準日(すなわち、エポック、base_date timestamp default current_timeのようなもの)を定義します。他のすべてのデータは、そのエポックデータの後の間隔として定義されます(例:base_date + interval '1 day')。私のテストの荒いランタイムを知っているので、私はタイムスタンプをテスト中に絶対に超えないように設定することができます(例えば、ランタイムが秒のbase_dateの後の時間)。私のテストデータに変数を入れておくと、チェックするのが難しくなります。
  • の使用を中止し、通常の使用(Javaの場合)でSystem.currentTimeMillis()またはnew java.util.Date()(いずれの場合も 'now')のようなものになり、私のテストでは一定の日付。私はこのソリューションのファンではありません。なぜなら、a)通常の使用法(テストの外)で必要とされない変更を導入するためです。b)追加のパラメータは追加のエラーの原因です。
  • 'testing mode'がオンであり、代わりに定数を返す必要があることを示す特定の値が存在しない限り、current_timestampを返すストアドプロシージャを定義します。これは実際にはうまくいくかもしれませんが、Postgresでcurrent_timestampが返す簡単な方法があれば必要ではないかもしれません。代わりに型付けされたリテラル値をクエリ文字列にcurrent_timestampを交換し、データベース自体に何かをしようとしている、またはちょうどあなたがあなたのユニットテストであなたのデータベース呼び出しをラップすることができ、特定のテストを可能にするようにコードをリファクタリングする
+0

** single **トランザクションですべてを実行すると、その間に 'current_timestamp'は変更されません –

答えて

1

。たとえば:

public ResultSet executeQuery(String sql) { 
    return wrapped.executeQuery(
     sql.replaceAll("\\bcurrent_timestamp\\b", 
         "'20160425 10:12'::timestamptz")); 
} 

それはこれらのインターフェースは、メソッドの多くを定義すると、首の痛みは、直接ConnectionStatementラッパーを実装するかもしれません。既に他のものでJDBCアクセスをラップしている場合や、Mockitoのspy()のような部分モックを作成できるモックライブラリを使用している場合は、より簡単にできます。いずれかを行っていない場合は、java.reflect.Proxyを使用してください。

関連する問題