PowerMockito 不会嘲笑 Thread.sleep

2024-01-10

这是我的设置不起作用:

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();
}

某个类.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 没有嘲笑Thread.sleep()当它真正被调用时Someclass但工作时很奇怪Thread.sleep()在 JUnit 本身内部调用。

我知道包装Thread.sleep()另一种方法可以解决我的问题,但我只想知道正确的模拟方法Thread.sleep()与 PowerMockito。


工作示例here https://github.com/codetojoy/gists_java/tree/master/egg_StackOverflow_64691825。请注意,这集中于“如何模拟Thread.sleep”并且不包括您的示例中的所有原始代码。(我不确定您的示例是否足够完整以准确地重现。)

如果“正在测试”的类看起来像这样(我们记录了经过的时间)Thread.sleep):

(Edit:请注意,空的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 秒,共 3 次),但是使用模拟,输出为:

TRACER caught exception: mock error
TRACER caught exception: mock error
TRACER caught exception: mock error
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PowerMockito 不会嘲笑 Thread.sleep 的相关文章

随机推荐