2013-04-04 63 views
0

我目前正在尝试使用PowerMock 1.4.10对一些遗留代码进行一些单元测试,并且有一种方法是我试图测试有静态无效调用和静态非无效调用。有没有办法在抑制静态void调用的同时模拟静态非void调用?抑制一个无效的静态方法和与PowerMock在同一类中的静态方法

@RunWith(PowerMockRunner.class) 
@PrepareForTest(ClassUnderTest.class) 
public class TestClass { 

    @Test 
    public void test() { 
     MemberModifier.suppress(StaticClass.class.getDeclaredMethod("logRandom")); 

     PowerMock.mockStatic(StaticClass.class); 
     expect(StaticClass.isLogOn()).andReturn(true); 
     PowerMock.replay(StaticClass.class); 

     ClassUnderTest test = new ClassUnderTest(); 
     test.methodToTest(); 

     assertTrue(test.tested); 

     PowerMock.verify(StaticClass.class); 
    } 
} 


public class ClassUnderTest { 
    public boolean tested = false; 

    public void methodToTest() { 
     if (StaticClass.isLogOn()) { 
      StaticClass.logRandom(); 
     } 
    } 

} 

public class StaticClass { 

    public static void logRandom() { 
     System.out.println("Do something"); 
    } 

    public static boolean isLogOn() { 
     return (Math.random() > .5); 
    } 
} 

但是,当我尝试这样做,我得到以下堆栈跟踪:

java.lang.IllegalStateException: no last call on a mock available 
    at org.easymock.EasyMock.getControlForLastCall(EasyMock.java:521) 
    at org.easymock.EasyMock.expect(EasyMock.java:499) 
    at TestClass.test(TestClass.java:20) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:307) 
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:88) 
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:96) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282) 
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86) 
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120) 
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33) 
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:118) 
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:102) 
    at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

是否有人在如何处理这个任何想法?

回答

1

我已经用PowerMock和Mockito的组合PowerMockito成功测试了静态。你可以用PowerMockito.mockStatic而不是PowerMock版本来嘲弄你的静态调用。完成后,您可以拨打Mockito.when来处理该呼叫。

PowerMockito.mockStatic(StaticClass.class); 
Mockito.when(StaticClass.isLogOn()).thenReturn(true); 

当测试运行时,当它到达的if (StaticClass.isLogOn()) {测试执行时,嘲笑应该介入并返回true,这踢入逻辑用于调用logRandom。从这里,你可以尝试使用spy来让它调用实际的代码,或者你可以根据需要嘲笑那个logRandom调用。你可以使用spyPowerMocktio Page下的Partial Mocking找到更多关于模拟的信息。