测试的过程中,经常会出现的情况是有些需要mock的对象是在方法调用过程中创建的;我们不能通过创建mock对象然后设置到被测对象中的方式来实现;
天无绝人之路,jmockit给我们提供了可以mock一个类的所有被创建的对象,就是说不管你是在一次执行过成中的任何位置使用该类,都可以自动的被mock;
import static mockit.Deencapsulation.*;
@Test
public void testMdm(@Mocked final HttpProtobufComponentExecutor mybatisComponentExecutor) throws EngineException {
/*测试调用参数*/
Map params = new HashMap();
params.put("acctId" , 10);
/*被mock对象方法的返回值*/
final Map mockResult = new HashMap();
mockResult.put("acctId",20);
mockResult.put("acctName","test");
mockResult.put("acctStatus",10);
/*
mock逻辑:
1.mock调用过程中遇到的所有HttpProtobufComponentExecutor类对象的私有方法invokeTainluRpcService
*/
new NonStrictExpectations(HttpProtobufComponentExecutor.class){
{
invoke(mybatisComponentExecutor, "invokeTainluRpcService", withAny(ConsumerConfig.class),withAny(Object.class),anyString); result = mockResult;
}
};
/*
callComponentPB方法调用中会创建HttpProtobufComponentExecutor对象,并且调用invokeTainluRpcService方法,该方法由上面的mock逻辑模拟
*/
Object result = this.callComponentPB("mdmQueryAcct", params);
Assert.assertNotNull(result);
System.out.println(result);
}
注意:
Deencapsulation.invoke方法中不能使用any这样的参数,否则必须使用正确类型的参数;
例如下面的调用会报异常
invoke(mybatisComponentExecutor, "invokeTainluRpcService", withAny(ConsumerConfig.class),any,anyString); result = mockResult;
java.lang.IllegalArgumentException: Invalid null value passed as argument 1
at com.baidu.rigel.bpip.ka.AcsTest$1.<init>(AcsTest.java:137)
at com.baidu.rigel.bpip.ka.AcsTest.testMdm(AcsTest.java:135)