Как протестировать метод с помощью sleep () с Java?

У меня есть следующий метод, и я изо всех сил пытаюсь получить 100% покрытие кода.

public final class SleepingHelper {
    public static void sleepInMillis(Duration timeOfNextTry) {
        try {
            Thread.sleep(timeOfNextTry.toMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Вопрос в том, как заставить Thread.sleep выбросить исключение?

Изменить: поскольку он был отмечен как дубликат, мне все еще интересно, что я утверждаю в тесте? Другой вопрос более общий.


person Paul Fournel    schedule 23.01.2016    source источник
comment
нацеленность на 100% покрытие обманчива. Тестирование этого метода не даст вам никаких дополнительных преимуществ, кроме увеличения охвата. Какова цель тестирования этого метода? Кроме того, что Thread.sleep не работает. Это очевидно из-за вашего вопроса об утверждении, что это тест, который вы не хотите писать!   -  person Emerson Cod    schedule 24.01.2016
comment
Я согласен, но я работаю над проектом, в котором мы обеспечиваем 100% покрытие кода.   -  person Paul Fournel    schedule 24.01.2016
comment
если это обязательство по проекту, я бы создал тест без каких-либо утверждений - вы получите свои 100%, и тест не провалится ... или AssertEquals(true, true).   -  person Emerson Cod    schedule 24.01.2016
comment
Сделайте сенс. Я сделаю что-то подобное.   -  person Paul Fournel    schedule 24.01.2016


Ответы (4)


Вам нужно прервать его из другого потока. Например:

 Thread t = new Thread() {
     public void run () {
        SleeperMillis.sleepInMillis(new Duration(10000000l));
     }
 }.start();
 Thread.sleep(100); // let the other thread start
 t.interrupt;
person Dima    schedule 23.01.2016
comment
Спасибо! это помогает, но что бы вы утверждали в тесте? - person Paul Fournel; 24.01.2016
comment
Я не знаю, это зависит от того, какое поведение или контракт вы пытаетесь проверить. Что именно вы хотите протестировать? Что jdk правильно реализует sleep ()? Обычно не рекомендуется тестировать поведение функций, которые вы не писали. - person Dima; 24.01.2016

Вам не нужно фактически прерывать поток. Вы можете использовать PowerMockito для имитации статического метода Thread.sleep()

@RunWith(PowerMockRunner.class)
@PrepareForTest(Thread.class)
public class TestClass {

    @Test
    public void testSleepInMillis() throws Exception {
        PowerMockito.mockStatic(Thread.class);
        PowerMockito.doThrow(new InterruptedException ()).when(Thread.class);

        try {
            SleepHelper.sleepInMillis(11);
            fail("expected exception");
        } catch (InterruptedException e) {
            System.out.println("all good");
        }

    }
person Nir Levy    schedule 23.01.2016
comment
FTR это не работает в новом статическом издевательстве Mockito ... org.mockito.exceptions.base.MockitoException: невозможно имитировать статические методы java.lang.Thread, чтобы не мешать загрузке класса, что приводит к бесконечным циклам - person JGleason; 21.05.2021

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

Mocking - лучший вариант здесь.

Кстати, дело не только в том, что ваши тесты непредсказуемы, ваш код, который использует Thread.sleep в производстве, будет непредсказуемым по тем же причинам. Thread.sleep(some magic number goes here) обычно указывает на плохо написанную программу.

person Sleiman Jneidi    schedule 23.01.2016

Я бы не стал его тестировать. 100% покрытие избыточно. Однако сделать это можно так:

@Test
public void testException() throws Exception {

    // Capture the system error stream, so that we can test that the expected exception is printed.
    ByteArrayOutputStream capturedErrors = new ByteArrayOutputStream();
    System.setErr(new PrintStream(capturedErrors));

    // Create a new thread on which to run the candidate method.
    Thread thread = new Thread() {
        @Override
        public void run() {
            SleepingHelper.sleepInMillis(Duration.ofMillis(10));
        }
    };

    // Start the second thread.
    thread.start();

    // Interrupt the second thread. (The candidate method hasn't finished yet. It takes 10 milliseconds to run.)
    thread.interrupt();

    // Wait for the thread to die (and write out the stack-trace).
    thread.join();

    // Test that the expected exception's stack trace was printed to the system error stream.
    // The output should start with the exception's name.
    String output = capturedErrors.toString();
    int lengthOfExceptionName = "java.lang.InterruptedException".length();
    assertEquals(output.substring(0, lengthOfExceptionName), "java.lang.InterruptedException");
}
person whistling_marmot    schedule 23.01.2016