java - Thread.sleep 没有被 PowerMockito mock

标签 java multithreading junit 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();
}
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 不是在 mock Thread.sleep()当它实际被调用时 Someclass但在 Thread.sleep() 时奇怪地工作在 JUnit 本身内部调用。
我知道包装 Thread.sleep()另一种方法将解决我的问题,但我只想知道正确的模拟方法 Thread.sleep()使用 PowerMockito。

最佳答案

工作示例 here .请注意,这主要集中在“如何模拟 Thread.sleep”上,并不包括示例中的所有原始代码。 (我不确定您的示例是否足够完整以准确重现。)
如果“under test”类看起来像这样(我们记录了 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 秒(因为代码将 hibernate 5 秒,3 次),但使用模拟,输出为:
TRACER caught exception: mock error
TRACER caught exception: mock error
TRACER caught exception: mock error

关于java - Thread.sleep 没有被 PowerMockito mock ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64691825/

相关文章:

java - Junit-如何测试参数的无效使用

java - 通过调用另一个类进行 JUnit 测试

java - Cisco Webex API 异常

java - ConcurrentSkipListMap.compute() 对于相关更新安全吗?

c# - 用于大量、低延迟 http 请求的异步与线程

c++ - 一次加载Lua脚本,多线程多状态执行

java - 自定义 MongoDB spring 数据存储库

java - 在 Mac OSX 上将 JDK 7 或更高版本与 Android Studio 和 Eclipse 结合使用

java - 等待旗帜

java - 在 IntelliJ IDEA 中使用 JUnit RunListener