5
回答
easyMock求助!
华为云实践训练营,热门技术免费实践!>>>   
public class Context {
	public String getString(){
		return "just for test";
	}
}

抽象类

public abstract class Myexample {
	public abstract String getTest(String s);
	
	static Context getContext(){
		return new Context();
	} 
}

待测试的类

public class ExampleClass extends Myexample{
    private  String getMsg(String s){
       if ("yes".equals(s)){
           return getContext().getString();
       } else {
           return "no";
       }
    }
   
    public String getTest(String s){
       return this.getMsg(s);
    }
}

测试方法

 @Test
    public void testGetMsg() throws Exception {     
       Context con = PowerMock.createPartialMock(Context.class,"getString");
       ExampleClass ec = PowerMock.createPartialMock(ExampleClass.class, "getContext");
       PowerMock.expectPrivate(ec,"getContext").andReturn(con);
       EasyMock.expect(con.getString()).andReturn("just for test");
       EasyMock.replay(con);
       PowerMock.replayAll();
       ExampleClass econe=new ExampleClass();
       Method m=econe.getClass().getDeclaredMethod("ExampleClass",String.class);
       Object result=m.invoke("getTest", "yes");
       Assert.assertEquals("just for test",result);
       PowerMock.verifyAll();
       EasyMock.verify(con);
    }
运行测试方法时抛错java.lang.IllegalStateException: no last call on a mock available,

大神们求解。



举报
guyingll
发帖于5年前 5回/1K+阅
共有5个答案 最后回答: 5年前

PowerMock.expectPrivate(ec,"getContext").andReturn(con);这一句是有问题的,getContext是静态方法,而easymock的expect之类的方法是基于ThreadLocal来保存你最后调用的方法。所以对于静态方法的调用不能用这种方式来处理。

你可以考虑用PowerMock里面的针对static方法mock的处理方式来调用,plz check this link:http://code.google.com/p/powermock/wiki/MockStatic

p.s:

你的错误是从PowerMock.expectPrivate(ec,"getContext").andReturn(con);出来的。

java.lang.IllegalStateException: no last call on a mock available
	at org.easymock.EasyMock.getControlForLastCall(EasyMock.java:520)
	at org.easymock.EasyMock.expectLastCall(EasyMock.java:511)
	at org.powermock.api.easymock.PowerMock.doExpectPrivate(PowerMock.java:2248)
	at org.powermock.api.easymock.PowerMock.expectPrivate(PowerMock.java:1400)
	at org.powermock.api.easymock.PowerMock.expectPrivate(PowerMock.java:1411)
	at org.powermock.api.easymock.PowerMock.expectPrivate(PowerMock.java:1357)
	at com.yp.test.ExampleClassTest.testGetMsg(ExampleClassTest.java:31)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:66)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:312)
	at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:86)
	at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:94)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:296)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:112)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:73)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:284)
	at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84)
	at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:209)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:148)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
	at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
	at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
	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.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:42)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	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)
Method m=econe.getClass().getDeclaredMethod("getMsg",String.class);

Object result=m.invoke(econe, "yes");
上面方法调用应该是这个,但还是没有运行到这块就抛错了。。。


代码大概是这样的:

String expected  = "just for test";

/**  有时候那个getContext() 需要运行环境,可以mock掉。


   Method method = MemberMatcher.method(..., "getContext");

   Powermock.suppress(method);

 */

Powermock.replayAll();

ExampleClass tested=new ExampleClass();

String actual = (String)Whitebox.invoke(tested, "getMsg", "yes");

assertEqual(expected, actual);

PowerMock.verifyAll();

顶部