11

System.currentTimeMillis()いくつかのテスト目的で、何が返されるかを正確に予測したいと思います。System.currentTimeMillis()が呼び出されたときに返されるものをフリーズまたは手動で設定する方法はありますか?

4

6 に答える 6

27

一般的なコードでSystem.currentTimeMillis(など)を使用しないことを強くお勧めします。new Date()

代わりに、Clock「現在の時刻を提供するサービス」を表すインターフェースを作成してから、何かを使用するSystem.currentTimeMillis実装と、明示的に制御できる偽の実装を作成します。

依存性注入を使用して、このサービスのインスタンスを必要とするコードで利用できるようにします。実稼働ではSystem.currentTimeMillisバージョンを使用し、テストでは偽物を使用します。

これにより、時間を停止するだけでなく、好きなように設定することができます。そのため、期限切れにならないことがわかっている静的なテスト データを使用したり、境界などのトリッキーなことを簡単にテストしたりできます。私はこれを使用しました。私の野田時間プロジェクトでは、それが「現在の時間」に到達する方法であるという点で、多くのプロジェクトで非常にうまくアプローチしています。

Java でかなりの時間作業を行っている場合は、Joda Timeを使用し、Clockインターフェイスが次の値を返すようにすることをお勧めしInstantます。

public interface Clock {
    Instant now();
}
于 2013-07-01T06:12:30.307 に答える
18

はい、可能ですが、テスト コードの匂いです。

(このPowerMock の例のように) 静的メソッドをモックできるモック ライブラリを使用できますが、これを避け、他の回答が示唆するように時間データをカプセル化する必要があります。

PowerMockMockitoを使用したテストは次のようになります。

@RunWith(PowerMockRunner.class)
@PrepareForTest(System.class)
public class TestTime {

    @Test
    public void testTime() {
        PowerMockito.mockStatic(System.class);
        PowerMockito.when(System.currentTimeMillis()).thenReturn(42l);
        System.out.println(System.currentTimeMillis()); //prints 42

        //your test code here
    }

}
于 2013-07-01T06:14:45.340 に答える
1

Java 8 に組み込まれた新しい java.time パッケージには、「必要に応じて代替クロックをプラグインできるようにするための java.time.Clock インターフェースが含まれています。代わりにこれを使用してください。

于 2017-08-28T19:25:14.673 に答える
1

System.currentTimeMillis() をフリーズすることは可能ですか? いいえ

コードをテストできるようにする場合は、その時間値の周りに一種のラッパーを使用する必要があります

于 2013-07-01T06:05:15.133 に答える
-5

はい、解決策は存在します:

テスト目的で、独自のラッパーシステムを作成できます。たとえば、

package my.pack;

import java.io.PrintStream;

public class System
{
    // reuse standard System.out:
    public static PrintStream out = java.lang.System.out;

    // do anything with chosen method
    public static long currentTimeMillis()
    {
        return 1234567;
    }

}

テストしたいクラスにインポートします

import my.pack.System;

その場合、System へのすべての呼び出しは独自の System クラスを介して渡されます。

ノート:

  • これは、「System.currentTimeMillis() を傍受する方法」の解決策です。

  • これは自動テストには適していません

  • これは「良いプログラムを設計する方法」の例ではありません。優れた設計を求める場合は、コードをリファクタリングし、 System.currentTimeMillis() を置き換える必要があります-他の回答を参照してください。

于 2013-07-01T06:28:01.623 に答える