7

本体に日付が含まれるeasymockを使用して、次のようなメソッドをモックしています。

public void testedMethod() {
    ...
    if (doSomething(new Date())) {
    ...
}

そして私のテストは次のようになります:

public void testThatMethod() {
    ...
    expect(testedClass.testedMethod(new Date())).andReturn(false);
    ...
}

しかし、テストを実行すると、次のようなエラーが発生することがあります。

予期しないメソッド呼び出しtestedMethod(Thu Jan 28 09:45:13 GMT-03:00 2010):testedMethod(Thu Jan 28 09:45:13 GMT-03:00 2010):期待:1、実際:0

日付が若干違うことがあるからだと思います。私はいくつかの柔軟な期待を試みましたが成功しませんでした。これを回避する方法はありますか?

4

6 に答える 6

5

私たちは常に同様の問題に直面しており、これらは私が見る代替案です。

  1. メソッドへのパラメーターとして日付を提供します (+) クイック チェンジ (-) 少し汚い - 「今すぐ」を使用したい場合は、インターフェイスも汚染します
  2. コラボレーター「QueryCurrentDateProvider」から日付を取得します (+) まだかなり速いです (+) モックすることもできます -> 同じ日付を使用していると確信しています (-) 同様のことを行う必要があるすべてのサービスに対して作成された不要なコラボレーター
  3. 実際にやりたいことを抽象化する独自の EasyMock 引数マッチャーを作成します。これを (+) 最もクリーンなソリューション ( +) 生産的なコードに変更はありません (-) 独自のマッチャーを作成する必要があります (ただし、なぜ EasyMock にマッチャーがないのかわかりません)
  4. 「new Date()」をプライベート メソッドに移動し、このメソッドを PowerMock のようなものでモックします (+) 迅速な (+) 生産的なコードへの小さな変更 (-) 依存関係としてパワー モックを導入します
  5. パラメーターを Date から String に変更し、一般的なパターンを使用して、メソッドを呼び出す前に日付を文字列に変換します (+) クイック (+) 追加のコードなし、テスト サイトで必要なライブラリ (-) 日付をフォーマットする必要がありますメソッドを呼び出す前に、呼び出されたメソッドの日付を解析します

したがって、それは本当にあなたの個人的な好みになります。現在のタイムスタンプを頻繁に使用する場合は、引数マッチャーをお勧めします。これは、この投資がすぐに報われるためです。

于 2012-05-09T14:54:22.627 に答える
4

new Date()の使用をやめ、代わりに一定時間のカレンダーを使用してください。

//Declare the Calendar in your test method
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(0l);

//receive the calendar to be used in testedClass constructor
public void testedMethod() {
    ...
    if (doSomething(cal.getTime())) {
    ...
}

//use the same calendar to make the assertion
public void testThatMethod() {
    ...
    expect(testedClass.(testedMethod(cal.getTime())).andReturn(false);
    ...
}
于 2010-01-28T17:55:20.703 に答える
3

このスレッドを見つけたばかりで、何時間も立ち往生していた問題を解決するのに役立ちました.

私は私の2セントを共有すると思った:

日付の値を気にせず、それが Date オブジェクトであることだけを知りたい場合は、EasyMock の事前定義されたマッチャーを使用してください。

EasyMock.expect(objectMock.isPollingTimeOut(EasyMock.eq(600000L), EasyMock.isA(Date.class), EasyMock.eq(someMock))).andReturn(false);

マッチャーを使用したら、私が行ったように、テストしているメソッドのすべての引数に対してマッチャーを使用する必要があることを忘れないでください。

于 2012-09-28T07:32:56.600 に答える
2

失敗した理由を正確に把握できる場合は、独自のマッチャーを作成して、日付の一致をより柔軟にすることができます。マッチャーのセクションを参照してくださいhttp://easymock.org/EasyMock2_2_Documentation.html

于 2010-01-28T14:26:38.047 に答える
2

日付のミリ秒部分が異なる可能性があります。Calendar.set()日付オブジェクトを作成する前に、おそらくゼロにする必要があります。

Calendar myCalendar = Calendar.getInstance();
myCalendar.set(Calendar.MILLISECOND, 0);
Date testDate = myCalendar.getTime();

しかし、それは推測です:)

于 2010-01-28T14:28:48.357 に答える
0

緩やかな日付比較には、カスタム EasyMock Matcher を使用します。日付が互いに 1 秒以内にあるかどうかを確認する例を次に示します。

public class MyEasyMockMatchers {

    public static Date withinSecondOf(Date value){
        EasyMock.reportMatcher(new IArgumentMatcher() {
            @Override
            public boolean matches(Object argument) {
                return argument instanceof Date
                        && Math.abs(((Date) argument).getTime() - value.getTime()) < Timer.ONE_SECOND;
            }

            @Override
            public void appendTo(StringBuffer buffer) {
                buffer.append(value.toString());
            }
        });
        return null;
    }
}

次に、テストで次を使用します。

import static my.package.MyEasyMockMatchers.*;
...
expect(testedClass.testedMethod(withinSecondOf(new Date())))
        .andReturn(false);

1 つのマッチャーを使用する場合は、expect 全体に対してマッチャーを使用する必要があることに注意してください。例えば:

expect(testedClass.testedMethod(42, "hello", new Date()))
        .andReturn(false);
// becomes
expect(testedClass.testedMethod(eq(42), eq("hello"), withinSecondOf(new Date())))
        .andReturn(false);

参照: https://easymock.org/user-guide.html#verification-expectations

于 2020-06-24T16:57:04.890 に答える