Thread.sleep 没有被 PowerMockito 嘲笑
Thread.sleep is not getting mocked with PowerMockito
我的设置无效:
SomeclassTest.java
@RunWith(PowerMockRunner.class)
@PowerMockIgnore("javax.management.*")
@PrepareForTest({SomeclassTest.class, Someclass.class})
public class SomeclassTest{
@InjectMocks
private Someclass someclass;
@Test(expected=None.class)
public void testRun() throws Exception{
PowerMockito.mockStatic(Thread.class);
PowerMockito.doThrow(new RuntimeException()).when(Thread.class);
Thread.sleep(Matchers.anyLong());
try {
Thread.sleep(5L);
}catch(Exception ex) {
System.out.println("working"); // this is working
}
WhiteboxImpl.invokeMethod(someclass, "run"); // not working in someclass
PowerMockito.verifyStatic();
}
Someclass.java
@Named("Someclass")
public class Someclass extends Thread{
@Override
public void run() {
while (true) {
try {
// clear interruption
interrupted();
long noOfRec= 0;
if (noOfRec> 0) {
Thread.sleep(shortInterval);
} else {
Thread.sleep(longInterval);
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (Exception ex) {
}
}
}
我的问题是 PowerMockito 在 Someclass
中实际调用时并没有模拟 Thread.sleep()
,但在 JUnit 本身内部调用 Thread.sleep()
时却奇怪地工作。
我知道用另一种方法包装 Thread.sleep()
可以解决我的问题,但我只想知道使用 PowerMockito 模拟 Thread.sleep()
的正确方法。
工作示例here。请注意,这集中于“如何模拟 Thread.sleep
”,并不包括示例中的所有原始代码。 (我不确定您的示例是否足够完整,无法准确重现。)
如果 class“正在测试”看起来像这样(我们记录 Thread.sleep
的经过时间):
(编辑: 注意,空的 catch (Exception ex)
块现在将记录一条消息。
public class SomeClass extends Thread {
private long shortInterval = 100;
private long longInterval = 5000;
@Override
public void run() {
// original code had `while (true)` but this is simpler as an illustration:
int counter = 0;
while (counter < 3) {
try {
// clear interruption
interrupted();
long noOfRec = 0;
if (noOfRec > 0) {
Thread.sleep(shortInterval);
} else {
// in addition to Thread.sleep, log the elapsed time
long startTime = System.nanoTime();
Thread.sleep(longInterval);
long elapsedInNanos = System.nanoTime() - startTime;
long elapsedInSeconds = TimeUnit.SECONDS.convert(elapsedInNanos, TimeUnit.NANOSECONDS);
System.out.println(String.format("TRACER elapsed in seconds: %d", elapsedInSeconds));
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (Exception ex) {
System.out.println("TRACER caught exception: " + ex.getMessage());
}
counter++;
}
}
}
然后考虑以下测试:
@RunWith(PowerMockRunner.class)
@PowerMockIgnore("javax.management.*")
@PrepareForTest({SomeClass.class, Thread.class})
public class SomeClassTestCase {
@Test(expected=Test.None.class)
public void testRun() throws Exception {
PowerMockito.mockStatic(Thread.class);
PowerMockito.doThrow(new RuntimeException("mock error")).when(Thread.class);
Thread.sleep(Matchers.anyLong());
SomeClass someClass = new SomeClass();
// test
someClass.run();
}
}
没有模拟,测试将耗时约 15 秒(因为代码将休眠 5 秒,三次),但使用模拟,输出为:
TRACER caught exception: mock error
TRACER caught exception: mock error
TRACER caught exception: mock error
我的设置无效:
SomeclassTest.java
@RunWith(PowerMockRunner.class)
@PowerMockIgnore("javax.management.*")
@PrepareForTest({SomeclassTest.class, Someclass.class})
public class SomeclassTest{
@InjectMocks
private Someclass someclass;
@Test(expected=None.class)
public void testRun() throws Exception{
PowerMockito.mockStatic(Thread.class);
PowerMockito.doThrow(new RuntimeException()).when(Thread.class);
Thread.sleep(Matchers.anyLong());
try {
Thread.sleep(5L);
}catch(Exception ex) {
System.out.println("working"); // this is working
}
WhiteboxImpl.invokeMethod(someclass, "run"); // not working in someclass
PowerMockito.verifyStatic();
}
Someclass.java
@Named("Someclass")
public class Someclass extends Thread{
@Override
public void run() {
while (true) {
try {
// clear interruption
interrupted();
long noOfRec= 0;
if (noOfRec> 0) {
Thread.sleep(shortInterval);
} else {
Thread.sleep(longInterval);
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (Exception ex) {
}
}
}
我的问题是 PowerMockito 在 Someclass
中实际调用时并没有模拟 Thread.sleep()
,但在 JUnit 本身内部调用 Thread.sleep()
时却奇怪地工作。
我知道用另一种方法包装 Thread.sleep()
可以解决我的问题,但我只想知道使用 PowerMockito 模拟 Thread.sleep()
的正确方法。
工作示例here。请注意,这集中于“如何模拟 Thread.sleep
”,并不包括示例中的所有原始代码。 (我不确定您的示例是否足够完整,无法准确重现。)
如果 class“正在测试”看起来像这样(我们记录 Thread.sleep
的经过时间):
(编辑: 注意,空的 catch (Exception ex)
块现在将记录一条消息。
public class SomeClass extends Thread {
private long shortInterval = 100;
private long longInterval = 5000;
@Override
public void run() {
// original code had `while (true)` but this is simpler as an illustration:
int counter = 0;
while (counter < 3) {
try {
// clear interruption
interrupted();
long noOfRec = 0;
if (noOfRec > 0) {
Thread.sleep(shortInterval);
} else {
// in addition to Thread.sleep, log the elapsed time
long startTime = System.nanoTime();
Thread.sleep(longInterval);
long elapsedInNanos = System.nanoTime() - startTime;
long elapsedInSeconds = TimeUnit.SECONDS.convert(elapsedInNanos, TimeUnit.NANOSECONDS);
System.out.println(String.format("TRACER elapsed in seconds: %d", elapsedInSeconds));
}
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
} catch (Exception ex) {
System.out.println("TRACER caught exception: " + ex.getMessage());
}
counter++;
}
}
}
然后考虑以下测试:
@RunWith(PowerMockRunner.class)
@PowerMockIgnore("javax.management.*")
@PrepareForTest({SomeClass.class, Thread.class})
public class SomeClassTestCase {
@Test(expected=Test.None.class)
public void testRun() throws Exception {
PowerMockito.mockStatic(Thread.class);
PowerMockito.doThrow(new RuntimeException("mock error")).when(Thread.class);
Thread.sleep(Matchers.anyLong());
SomeClass someClass = new SomeClass();
// test
someClass.run();
}
}
没有模拟,测试将耗时约 15 秒(因为代码将休眠 5 秒,三次),但使用模拟,输出为:
TRACER caught exception: mock error
TRACER caught exception: mock error
TRACER caught exception: mock error