如何用Java测试一个使用sleep()的方法?

时间:2016-01-23 21:17:30

标签: java junit

我有以下方法,我很难获得100%的代码覆盖率。

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

问题是如何强制Thread.sleep抛出异常?

编辑:因为它被标记为重复,我仍然想知道我会在测试中断言什么?另一个问题是更通用的。

4 个答案:

答案 0 :(得分:6)

您需要从另一个线程中断它。例如:

have_ingredients(food).map(|f| can_cook(f))

答案 1 :(得分:5)

您不需要实际中断线程。您可以使用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");
        }

    }

答案 2 :(得分:4)

您没有对其进行测试,因为您无法断言其结果,并且您无法断言,因为Thread.sleep不准确或无法保证在此段时间内保持睡眠状态,测试结果因运行而异。

Mocking是一个更好的选择。

顺便说一句,不仅仅是您的测试无法预测,因此在生产中使用Thread.sleep的代码由于同样的原因将无法预测。 Thread.sleep(some magic number goes here)通常表示编写错误的程序。

答案 3 :(得分:0)

我不会费心去测试它。 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");
}