Mocking behaviour resets after each test with PowerMock
我正在使用PowerMock编写单元测试,模拟某些util类的行为。 为测试类定义一次行为(通过@BeforeClass批注)会导致:
- 第一次测试调用以返回模拟值
- 第二次测试返回真实方法的返回值
样例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) @PrepareForTest( {A.class, B.class}) public class TestMockedMethods { private static B b; @BeforeClass public static void setUp() { PowerMockito.mockStatic(A.class); PowerMockito.when(A.getVal()).thenReturn("X"); b = PowerMockito.mock(B.class); PowerMockito.when(b.getVal()).thenReturn("Y"); } @Test public void test1() { // PASS Assert.assertEquals("X", A.getVal()); Assert.assertEquals("Y", b.getVal()); } @Test public void test2() { // FAIL Assert.assertEquals("X", A.getVal()); // actual="A" Assert.assertEquals("Y", b.getVal()); // actual="B" } } class A { static String getVal() { return"A"; } } class B { String getVal() { return"B"; } } |
任何想法为什么第二次测试失败了?
方法
1 | MockRepository.addAfterMethodRunner(new MockitoStateCleaner()); |
这个可运行的清理Mockito的内部状态:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | private static class MockitoStateCleaner implements Runnable { public void run() { clearMockProgress(); clearConfiguration(); } private void clearMockProgress() { clearThreadLocalIn(ThreadSafeMockingProgress.class); } private void clearConfiguration() { clearThreadLocalIn(GlobalConfiguration.class); } private void clearThreadLocalIn(Class< ? > cls) { Whitebox.getInternalState(cls, ThreadLocal.class).set(null); final Class< ? > clazz = ClassLoaderUtil.loadClass(cls, ClassLoader.getSystemClassLoader()); Whitebox.getInternalState(clazz, ThreadLocal.class).set(null); } } |
因此,您应该在每次测试之前执行setUp。
1 2 3 4 5 6 7 8 | @Before public void setUp() { PowerMockito.mockStatic(A.class); PowerMockito.when(A.getVal()).thenReturn("X"); b = PowerMockito.mock(B.class); PowerMockito.when(b.getVal()).thenReturn("Y"); } |