web-dev-qa-db-ja.com

Mockitoでスタブメソッドの応答を遅らせることはできますか?

現在、単体テストを書いています。実装のタイムアウト処理をテストするために、Mockitoを使用して長期実行メソッドをシミュレートする必要があります。 Mockitoで可能ですか?

このようなもの:

when(mockedService.doSomething(a, b)).thenReturn(c).after(5000L);
49
user961548

スレッドを目的の時間だけスリープさせることができます。気をつけてください-そのようなことはあなたの自動化されたテストの実行を本当に遅くする可能性があるので、あなたは別のスイートでそのようなテストを分離したいかもしれません

これは次のようになります。

when(mock.load("a")).thenAnswer(new Answer<String>() {
   @Override
   public String answer(InvocationOnMock invocation){
     Thread.sleep(5000);
     return "ABCD1234";
   }
});
59
K.L.

Mockito 2.8.44以降、この目的のためにorg.mockito.internal.stubbing.answers.AnswersWithDelayが利用可能になりました。以下に使用例を示します

 doAnswer( new AnswersWithDelay( 1000,  new Returns("some-return-value")) ).when(myMock).myMockMethod();
11
Viswanath

このためのユーティリティを作成しました:

import Java.time.Duration;
import Java.util.concurrent.TimeUnit;

import static org.mockito.Mockito.doAnswer;

public class Stubber {

    public static org.mockito.stubbing.Stubber doSleep(Duration timeUnit) {
        return doAnswer(invocationOnMock -> {
            TimeUnit.MILLISECONDS.sleep(timeUnit.toMillis());
            return null;
        });
    }

    public static <E> org.mockito.stubbing.Stubber doSleep(Duration timeUnit, E ret) {
        return doAnswer(invocationOnMock -> {
            TimeUnit.MILLISECONDS.sleep(timeUnit.toMillis());
            return ret;
        });
    }

}

そして、あなたのテストケースでは単純に以下を使用します:

doSleep(Duration.ofSeconds(3)).when(mock).method(anyObject());
7
Simon Ludwig

単体テストの場合は、実際のThread.sleep(long l)を呼び出すメソッドを作成してから、そのメソッドをモックすることをお勧めします。それにより、あなたはあなたのテストがあなたが望む限り待っていると思わせる素晴らしい動作でテストを注入することができます。これにより、瞬く間に多くのテストを実行し、さまざまな時間関連のシナリオをテストできます。これを使用する前に、UnitTestを6分間実行しました。現在、200ms未満です。

public class TimeTools {
public long msSince(long msStart) {
    return ((System.nanoTime() / 1_000_000) - msStart);
}

public long msNow() {
    return (System.nanoTime() / 1_000_000);
}

public Boolean napTime(long msSleep) throws InterruptedException {
    Thread.sleep(msSleep);
    return true;
}
}
-----------------------------------
@Mock
TimeTools Timetools;

@TEST
public void timeTest() {
when(timeTools.msSince(anyLong()))
            .thenReturn(0l)
            .thenReturn(5_500l)
            .thenReturn(11_000l)
            .thenReturn(11_000l)
            .thenReturn(0l)
            .thenReturn(11_000l)
            .thenReturn(11_000l)
            .thenReturn(0l)
            .thenReturn(29_000l);
}

しかし、最善のアプローチは、寝台車を注入し、それをock笑することです。そのため、テストでは実際に眠ることはありません。次に、単体テストは稲妻のように高速に実行されます。

0
Matej Lachman