我可以延迟使用Mockito的方法响应吗?

时间:2012-10-10 07:11:32

标签: java junit mocking mockito

我现在正在编写单元测试。我需要用Mockito模拟长期方法来测试我的实现的超时处理。 Mockito可以吗?

这样的事情:

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

4 个答案:

答案 0 :(得分:57)

您可以简单地让线程在预期的时间内休眠。注意这一点 - 这样的事情确实会减慢你的自动测试执行速度,所以你可能想要在一个单独的套件中隔离这些测试

看起来与此类似:

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

答案 1 :(得分:6)

我为此创建了一个utils:

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());

答案 2 :(得分:6)

来自mockito 2.8.44, org.mockito.internal.stubbing.answers.AnswersWithDelay 可用于此目的。这是一个示例用法

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

答案 3 :(得分:0)

单元测试更好的方法是创建调用实际Thread.sleep(long l)然后模拟该方法的方法。 有了这个,您可以为您的测试注入令人敬畏的行为,导致您的测试认为它等待您想要的时间。 有了这个,你可以在眨眼间进行大量的测试,并且仍然可以测试不同的时间相关场景。 在使用它之前,我的UnitTest运行了六分钟。现在它不到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);
}

但最好的方法是注入睡眠者,然后嘲笑它。所以在你的测试中,你实际上不会睡觉。然后你的单元测试会像闪电那样快速运行。