java 如何用PowerMock模拟Thread.sleep()?

6qftjkof  于 2023-01-11  发布在  Java
关注(0)|答案(3)|浏览(340)

如何用PowerMock模拟Thread.sleep()?
示例接口和类:

public interface Machine {

    void sleep(long millis);
}

public class MachineImpl
implements Machine {

    private static final Logger logger = Logger.getLogger(MachineImpl.class);

    @Override
    public void sleep(long millis) {
        try {
            if (millis > 0) {
                logger.trace(String.format("Try to sleep for %d millis...", millis));
                Thread.sleep(millis);
            }
        }
        catch (InterruptedException e) {
            logger.trace("Full exception", e);
        }
    }
}
56lgkhnf

56lgkhnf1#

这花了我一段时间才弄明白,所以我在回答我自己的问题。

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)  // important
@PrepareForTest(MachineImpl.class)  // important: do not use Thread.class here
public class MachineImplTest {

    private MachineImpl classUnderTest;

    @Before
    public void beforeEachTest() {
        classUnderTest = new MachineImpl();
    }

    @Test
    public void sleep_Pass() {
        classUnderTest.sleep(0);
        classUnderTest.sleep(-100);
        classUnderTest.sleep(+100);
    }

    @Test
    public void sleep_Pass2() {
        // We do not want to mock all methods, only specific methods, such as Thread.sleep().
        // Use spy() instead of mockStatic().
        PowerMockito.spy(Thread.class);

        // These two lines are tightly bound.
        PowerMockito.doThrow(new InterruptedException()).when(Thread.class);
        Thread.sleep(Mockito.anyLong());

        classUnderTest.sleep(0);
        classUnderTest.sleep(-100);
        classUnderTest.sleep(+100);
    }
}

如果您正在使用TestNG,请尝试以下操作:

import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;

@PrepareForTest(MachineImpl.class)  // important: do not use Thread.class here
public class MachineImplTest
extends PowerMockTestCase {
    ...
}

在此阅读更多关于TestNG + Mockito + PowerMock的信息:https://stackoverflow.com/a/35815153/257299

dgtucam1

dgtucam12#

这很有帮助。我最终确实使用了一些稍微不同的东西。我使用EasyMock而不是Mockito。

@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassUnderTest.class})
public class MyTest {
    @Before
    public void setUp() {
        PowerMock.mockStatic(Thread.class, methods(Thread.class, "sleep"));
        Thread.sleep(anyLong());
        EasyMock.expectLastCall().anyTimes();
    }
}

不需要在@PrepareForTest中使用Thread.class

cgyqldqp

cgyqldqp3#

在不使用PowerMockito的情况下,为Thread.sleep(anyLongValue)编写一个 Package 器方法,并将其移到实用程序类中,使用常规Mockito API模拟Utility类方法。

public void sleep(int duration) throws InterruptedException {
        Thread.sleep(duration);
 }

相关问题