我有以下方法,我很难获得100%的代码覆盖率。
public final class SleepingHelper {
public static void sleepInMillis(Duration timeOfNextTry) {
try {
Thread.sleep(timeOfNextTry.toMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
问题是如何强制Thread.sleep
抛出异常?
编辑:因为它被标记为重复,我仍然想知道我会在测试中断言什么?另一个问题是更通用的。
答案 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");
}