DolphinScheduler源码分析之EntityTestUtils类

  1 /*
  2  * Licensed to the Apache Software Foundation (ASF) under one or more
  3  * contributor license agreements.  See the NOTICE file distributed with
  4  * this work for additional information regarding copyright ownership.
  5  * The ASF licenses this file to You under the Apache License, Version 2.0
  6  * (the "License"); you may not use this file except in compliance with
  7  * the License.  You may obtain a copy of the License at
  8  *
  9  *    http://www.apache.org/licenses/LICENSE-2.0
 10  *
 11  * Unless required by applicable law or agreed to in writing, software
 12  * distributed under the License is distributed on an "AS IS" BASIS,
 13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  * See the License for the specific language governing permissions and
 15  * limitations under the License.
 16  */
 17 package org.apache.dolphinscheduler.common.task;
 18 
 19 import java.lang.reflect.Constructor;
 20 import java.lang.reflect.InvocationTargetException;
 21 import java.lang.reflect.Method;
 22 import java.util.*;
 23 
 24 /**
 25  * entity test utils
 26  * //该类是一个工具类,可以对传入的任何其他类进行检测,会依次调用类中的所有方法,用了反射机制。
 27  */
 28 public class EntityTestUtils {
 29     //初始化一个用来存储测试用的类型和对应的数值map数组
 30     private static final Map<String, Object> OBJECT_MAP = new HashMap<>();
 31     //遇到这些方法直接跳过,不测试。
 32     private static final String SKIP_METHOD = "getClass,notify,notifyAll,wait,equals,hashCode,clone";
 33     String
 34     static {
 35         //初始化参数数组
 36         OBJECT_MAP.put("java.lang.Long", 1L);
 37         OBJECT_MAP.put("java.lang.String", "test");
 38         OBJECT_MAP.put("java.lang.Integer", 1);
 39         OBJECT_MAP.put("int", 1);
 40         OBJECT_MAP.put("long", 1L);
 41         OBJECT_MAP.put("java.util.Date", new Date());
 42         OBJECT_MAP.put("char", '1');
 43         OBJECT_MAP.put("java.util.Map", new HashMap());
 44         OBJECT_MAP.put("boolean", true);
 45     }
 46     //传入要测试的类,可以看到,入参是一个Class类型的数组,代表可以同时测试多个类
 47     public static void run(List<Class> classList)
 48             throws IllegalAccessException, InvocationTargetException, InstantiationException {
 49         //一个个来,先取出第一个要测试的Class,比如是String.class
 50         for (Class temp : classList) {
 51             Object tempInstance = new Object();
 52             //获取要测试的类中所有的构造方法,不管是有参构造方法还是无参构造方法,比如String.class中的String()构造方法和String(String original) 等等
 53             Constructor[] constructors = temp.getConstructors();
 54             //遍历所有的构造方法
 55             for (Constructor constructor : constructors) {
 56                 //获取构造方法的参数类型,如果是无参构造方法,就会进入下面的if,如果是有参构造方法,就会进入下面的else去。
 57                 final Class<?>[] parameterTypes = constructor.getParameterTypes();
 58                 //无参构造方法,会进入这里的if
 59                 if (parameterTypes.length == 0) {
 60                     //用反射的机制,直接调用了这个无参构造方法,相当于完成了测试
 61                     tempInstance = constructor.newInstance();
 62                 } else {
 63                     //objects中存储的是参数的值,如果构造方法需要传入第一个是int,第二个是String,那么这个objects其实就是传入了(1,‘1’)这两个值
 64                     Object[] objects = new Object[parameterTypes.length];
 65                     //这里就是往objects中塞数据
 66                     for (int i = 0; i < parameterTypes.length; i++) {
 67                         objects[i] = OBJECT_MAP.get(parameterTypes[i].getName());
 68                     }
 69                     //用反射的机制,直接调用了这个有参数的构造方法,相当于完成了测试
 70                     tempInstance = constructor.newInstance(objects);
 71                 }
 72             }
 73             //这里是对类中的普通方法(除了构造方法外的所有其他方法)做测试
 74             Method[] methods = temp.getMethods();
 75             //遍历所有的普通方法
 76             for (final Method method : methods) {
 77                 //如果是需要跳过不进行测试的方法,那么就直接跳过
 78                 if (SKIP_METHOD.contains(method.getName())) {
 79                     break;
 80                 }
 81                 //同样也是获取到参数的类型
 82                 final Class<?>[] parameterTypes = method.getParameterTypes();
 83                 //如果是有参方法,进入if,无参方法进入else
 84                 if (parameterTypes.length != 0) {
 85                     //objects中存储的是参数的值,如果构造方法需要传入第一个是int,第二个是String,那么这个objects其实就是传入了(1,‘1’)这两个值
 86                     Object[] objects = new Object[parameterTypes.length];
 87                     //这里就是往objects中塞数据
 88                     for (int i = 0; i < parameterTypes.length; i++) {
 89                         objects[i] = OBJECT_MAP.get(parameterTypes[i].getName());
 90                     }
 91                     //用反射的机制,直接调用了这个有参数的方法,相当于完成了测试
 92                     method.invoke(tempInstance, objects);
 93                 } else {
 94                     //用反射的机制,直接调用了这个无参的方法,相当于完成了测试
 95                     method.invoke(tempInstance);
 96                 }
 97             }
 98         }
 99     }
100 }

 以下是DolphinScheduler源码中对这个类进行使用的方式,可以参考:

 1 /*
 2  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  * contributor license agreements.  See the NOTICE file distributed with
 4  * this work for additional information regarding copyright ownership.
 5  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  * (the "License"); you may not use this file except in compliance with
 7  * the License.  You may obtain a copy of the License at
 8  *
 9  *    http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package org.apache.dolphinscheduler.common.task;
18 
19 import org.apache.dolphinscheduler.common.task.sqoop.SqoopParameters;
20 import org.apache.dolphinscheduler.common.task.sqoop.sources.SourceHdfsParameter;
21 import org.apache.dolphinscheduler.common.task.sqoop.sources.SourceHiveParameter;
22 import org.apache.dolphinscheduler.common.task.sqoop.sources.SourceMysqlParameter;
23 import org.apache.dolphinscheduler.common.task.sqoop.targets.TargetHdfsParameter;
24 import org.apache.dolphinscheduler.common.task.sqoop.targets.TargetHiveParameter;
25 import org.apache.dolphinscheduler.common.task.sqoop.targets.TargetMysqlParameter;
26 import org.junit.Assert;
27 import org.junit.Test;
28 import java.util.ArrayList;
29 import java.util.List;
30 
31 /**
32  * sqoop parameter entity test
33  */
34 public class SqoopParameterEntityTest {
35 
36     @Test
37     public void testEntity(){
38         try {
39             List<Class> classList = new ArrayList<>();
40             classList.add(SourceMysqlParameter.class);
41             classList.add(SourceHiveParameter.class);
42             classList.add(SourceHdfsParameter.class);
43             classList.add(SqoopParameters.class);
44             classList.add(TargetMysqlParameter.class);
45             classList.add(TargetHiveParameter.class);
46             classList.add(TargetHdfsParameter.class);
47             EntityTestUtils.run(classList);
48         } catch (Exception e) {
49             Assert.fail(e.getMessage());
50         }
51     }
52 }
原文地址:https://www.cnblogs.com/lukairui/p/12525463.html