2、Mock接口
单元测试中的一个很重要的功能是mock外部接口。也就是说,对于指定的的接口,传入指定的借口,调用会返回指定的值。这个功能可以通过直接修改接口实现的方法来实现。
2.1 Mock一个接口
例如有这样的一个Servier接口:
- public interface Service {
- List<Integer> service(List<Integer> param);
- }
以及对应的实现类:
- public class ServiceImpl implements Service {
- @Override
- public List<Integer> service(List<Integer> param) {
- List<Integer> result = null;
- // ... xxx service
- // .... xxx method
- return result;
- }
- }
还有对应的单测类:
- public class ServiceTest {
- @Mocked
- private Service service = new ServiceImpl();
-
- @Test
- public void test(){
- List<Integer> result = service.service( null);
- if(result == null){
- System. out.println( "return null");
- } else{
- System. out.println( "return not null" );
- }
- }
- }
我们现在需要mock其中的service接口的实现类。假如我们现在要求在参数为null的条件下返回值为一个非空的数组。
那么我们可以在测试用例跑之前,先用Javassit修改ServiceImpl的class文件使得test方法返回一个ArrayList。实现如下:
- public static void modifyMethod(CtClass clazz,CtMethod method) throws Exception{
-
- StringBuilder body = new StringBuilder();
- body.append( "{if($1==null) return new java.util.ArrayList();else return null;}");
- method.setBody(body.toString());
-
- }
这里的实现很简单,我们使用Javassist直接把test方法的方法体替换为:
- if(param == null)//在Javassist里用$1代表第一个参数。
- return new java.util.ArrayList();
- else
- return null;
这样就可以实现我们需要的mock掉的方法。
2.2 查找需要Mock掉的方法
因为我们不能Mock掉所有的方法,所以需要根据具体的要求来Mock指定的方法,我们这里的要求是mock掉service方法,所以只需要查找到名称为service的方法来mock即可。
下面的方法用来查找我们要修改的service方法:
- public static void mock(CtClass ctClass) throws Exception{
- //1、查找名称为service的方法
- CtMethod method = ctClass.getDeclaredMethod( "service");
- //2、调用上面的方法来Mock调上面找到的service方法
- modifyMethod(ctClass, method);
- }
2.3 调用TestCase
接下来是如何调用我们的TestCase使得我们的Mock生效,因为我们是修改了ServiceImpl的class文件,所以在调用TestCase之前,需要先完成class文件的修改。具体的代码如下:
- public static void main(String[] args) throws Exception{
- //1、取得ServiceImpl
- ClassPool cp = ClassPool. getDefault();
- CtClass cc = cp.get( "ServiceImpl");
- //2、Mock掉service方法
- mock(cc);
- //3、写入到class文件里
- cc.writeFile( "F:/workspace/JavaAssit/bin/" );
- //4、调用TestCase
- ServiceTest serviceTest = new ServiceTest();
- serviceTest.test();
-
- }
运行一下,输出结果为return not null,这表明我们的mock代码起作用了。
阅读(5463) | 评论(0) | 转发(2) |