Подтвердить что ты не робот

Могу ли я отложить отложенный метод Mockito?

Сейчас я пишу модульные тесты. Мне нужно смоделировать долгосрочный метод с Mockito, чтобы проверить обработку времени ожидания выполнения. Возможно ли это с помощью Mockito?

Что-то вроде этого:

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

Ответ 1

Вы можете просто поставить поток в сон в течение требуемого времени. Следите за тем, что такие вещи могут действительно замедлить автоматическое выполнение теста, поэтому вы можете изолировать такие тесты в отдельном пакете

Он будет выглядеть примерно так:

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

Ответ 2

Я создал для этого 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());

Ответ 3

Намного лучше для модульных тестов - создать метод, который вызывает фактический Thread.sleep(long l), а затем издевается над этим методом. При этом вы можете придать вашему тесту удивительное поведение, в результате чего ваш тест будет считать, что он ждет столько, сколько захотите. При этом вы можете запускать много тестов в мгновение ока и все еще испытывать разные временные сценарии. Прежде чем использовать это, мой UnitTest продолжался шесть минут. Теперь его менее 200 мс.

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

Но лучший подход заключается в том, чтобы ввести спящего, а затем издеваться над ним. Поэтому в ваших тестах вы на самом деле не будете спать. Затем вы тестируете модульные тесты быстро, как молния.