Muk*_*uku 8 java junit multithreading mocking 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();
}
Run Code Online (Sandbox Code Playgroud)
某个类.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) {
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是 PowerMockitoThread.sleep()
在实际被调用时不是在嘲笑它,Someclass
而是Thread.sleep()
在 JUnit 本身内部被调用时奇怪地工作。
我知道Thread.sleep()
用另一种方法包装可以解决我的问题,但我只想知道Thread.sleep()
使用 PowerMockito 进行模拟的正确方法。
工作示例在这里。请注意,这集中于“如何模拟Thread.sleep
”,并不包括示例中的所有原始代码。(我不确定您的示例是否足够完整以准确重现。)
如果“正在测试”的类看起来像这样(我们记录 的经过时间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++;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后考虑以下测试:
@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();
}
}
Run Code Online (Sandbox Code Playgroud)
如果没有模拟,测试将花费约 15 秒(因为代码将休眠 5 秒,共 3 次),但是使用模拟,输出为:
TRACER caught exception: mock error
TRACER caught exception: mock error
TRACER caught exception: mock error
Run Code Online (Sandbox Code Playgroud)