Java 8 Clockを使用したクラスのユニットテスト
質問
Java 8 の導入
java.time.Clock
の引数として使用することができます。
java.time
オブジェクトの引数として使用することができ、本物の時計や偽物の時計を注入することができます。例えば、私はあなたが
Clock.fixed()
を作成し、次に
Instant.now(clock)
を呼び出すと、固定された
Instant
を返します。これはユニットテストに最適ですね。
しかし、私はこれをどのように使用するのが最善かについて困っています。私は、以下のようなクラスを持っています。
public class MyClass {
private Clock clock = Clock.systemUTC();
public void method1() {
Instant now = Instant.now(clock);
// Do something with 'now'
}
}
さて、このコードをユニットテストしたいと思います。私は
clock
を固定時間生成するように設定できるようにする必要があります。
method()
を異なる時刻でテストできるようにするためです。明らかに、私はリフレクションを使って
clock
メンバーを特定の値に設定するためにリフレクションを使うこともできますが、 リフレクションに頼る必要がないのはいいことです。私はパブリックな
setClock()
メソッドを作ることもできるが、それは間違っていると感じる。私は
Clock
引数を加えたくないのです。実際のコードではクロックを渡すことにこだわるべきではありませんから。
これを処理するための最良のアプローチは何でしょうか?これは新しいコードなので、私はクラスを再編成することができました。
編集: 明確にするために、私は単一の
MyClass
オブジェクトを構築し、その1つのオブジェクトに2つの異なるクロック値を表示させることができる必要があります (あたかも通常のシステムクロックが動いているかのように)。そのため、私はコンストラクターに固定クロックを渡すことができません。
どのように解決するのですか?
Jon Skeetの答えとコメントをコードにしてみましょう。
テスト中のクラスです。
public class Foo {
private final Clock clock;
public Foo(Clock clock) {
this.clock = clock;
}
public void someMethod() {
Instant now = clock.instant(); // this is changed to make test easier
System.out.println(now); // Do something with 'now'
}
}
ユニットテストです。
public class FooTest() {
private Foo foo;
private Clock mock;
@Before
public void setUp() {
mock = mock(Clock.class);
foo = new Foo(mock);
}
@Test
public void ensureDifferentValuesWhenMockIsCalled() {
Instant first = Instant.now(); // e.g. 12:00:00
Instant second = first.plusSeconds(1); // 12:00:01
Instant thirdAndAfter = second.plusSeconds(1); // 12:00:02
when(mock.instant()).thenReturn(first, second, thirdAndAfter);
foo.someMethod(); // string of first
foo.someMethod(); // string of second
foo.someMethod(); // string of thirdAndAfter
foo.someMethod(); // string of thirdAndAfter
}
}
関連
-
型に解決できない エラー解決
-
JAVA_HOME環境変数が正しく定義されていない問題を解決する
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] プライベートメソッド、フィールド、インナークラスを持つクラスをテストするにはどうすればよいですか?
-
[解決済み] Java内部クラスと静的ネストされたクラス
-
[解決済み] プライベートメソッドのユニットテストはどのように行うのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Solve モジュールのビルドに失敗しました。Error: ENOENT: no such file or directory エラー
-
ApplicationContextの起動エラーです。条件レポートを表示するには、アプリケーションを'de'で再実行します。
-
Jsoup-Crawlingの動作
-
keytool error: java.io.FileNotFoundException: cacerts (アクセス拒否されました。)
-
XXX型を囲むインスタンスがJavaでアクセスできない
-
eclipse にリソースリーク:'in' が閉じない
-
ecplise プロンプトが表示されます。"選択したものは起動できません。" "最近の起動はありません。"
-
org.xml.sax.SAXParseExceptionのエラー解決方法
-
htmlとwordの相互変換の実装(画像あり)
-
IDEAError:javaの依存性エラー。Annotation processing is not supported for module cycles...(アノテーション処理はモジュールサイクルではサポートされていません。