为应付公司单元覆盖率检查,想到了自动扫描所有entity类执行其中的set和get方法,以便快速提升单元测试代码覆盖率。借鉴了网上的代码,但是调试时发现了一个问题,并做了处理,即原始代码未作windows和linux区分,导致一开始代码在linux编译机上无法执行,下面附上所用代码。基于file类型亲测可以使用,jar类型未验证。
public class EntityTest {
@Test
public void test() throws Exception {
List<String> classNames = getClassName("com.xxxx.xxx.opp.xxx, true);
for (String className : classNames) {
System.out.println("====class name:" + className + "====");
try {
Class clazz = Class.forName(className);// 这里的类名是全名。。有包的话要加上包名
Object obj = clazz.newInstance();
Field[] fields = clazz.getDeclaredFields();
// 写数据
for (Field f : fields) {
try {
PropertyDescriptor pd = new PropertyDescriptor(f.getName(), clazz);
Method wM = pd.getWriteMethod();// 获得写方法
wM.invoke(obj, new Object[] { null });// 因为知道是int类型的属性,所以传个int过去就是了。。实际情况中需要判断下他的参数类型
Method rM = pd.getReadMethod();// 获得读方法
Integer num = (Integer) rM.invoke(obj);// 因为知道是int类型的属性,所以转换成integer就是了。。也可以不转换直接打印
} catch (Exception e) {
System.out.println(e);
}
}
} catch (Exception e) {
System.out.println(e);
}
}
}
/**
* 获取某包下(包括该包的所有子包)所有类
*
* @param packageName
* 包名
* @return 类的完整名称
* @throws Exception
*/
public static List<String> getClassName(String packageName) throws Exception {
return getClassName(packageName, true);
}
/**
* 获取某包下所有类
*
* @param packageName
* 包名
* @param childPackage
* 是否遍历子包
* @return 类的完整名称
* @throws Exception
*/
public static List<String> getClassName(String packageName, boolean childPackage) throws Exception {
List<String> fileNames = null;
// ClassLoader loader = Thread.currentThread().getContextClassLoader();
ClassLoader loader = EntityTest.class.getClassLoader();
String packagePath = packageName.replace(".", "/");
URL url = loader.getResource(packagePath);
System.out.println("====url name:" + url.toString() + "====");
System.out.println("====url path:" + url.getPath() + "====type:" + url.getProtocol());
if (url != null) {
String type = url.getProtocol();
if ("file".equals(type)) {
fileNames = getClassNameByFile(url.getPath(), null, childPackage);
} else if (("jar").equals(type)) {
fileNames = getClassNameByJar(url.getPath(), childPackage);
}
} else {
fileNames = getClassNameByJars(((URLClassLoader) loader).getURLs(), packagePath, childPackage);
}
return fileNames;
}
/**
* 从项目文件获取某包下所有类
*
* @param filePath
* 文件路径
* @param className
* 类名集合
* @param childPackage
* 是否遍历子包
* @return 类的完整名称
*/
private static List<String> getClassNameByFile(String filePath, List<String> className, boolean childPackage) {
List<String> myClassName = new ArrayList<String>();
File file = new File(filePath);
File[] childFiles = file.listFiles();
for (File childFile : childFiles) {
if (childFile.isDirectory()) {
if (childPackage) {
myClassName.addAll(getClassNameByFile(childFile.getPath(), myClassName, childPackage));
}
} else {
String childFilePath = childFile.getPath();
if (childFilePath.endsWith(".class")) {
if (System.getProperties().getProperty("os.name").startsWith("Windows")) {
childFilePath = childFilePath.substring(childFilePath.indexOf("\\classes") + 9,
childFilePath.lastIndexOf("."));
childFilePath = childFilePath.replace("\\", ".");
} else {
childFilePath = childFilePath.substring(childFilePath.indexOf("/classes") + 9,
childFilePath.lastIndexOf("."));
childFilePath = childFilePath.replace("/", ".");
}
myClassName.add(childFilePath);
}
}
}
return myClassName;
}
/**
* 从jar获取某包下所有类
*
* @param jarPath
* jar文件路径
* @param childPackage
* 是否遍历子包
* @return 类的完整名称
* @throws Exception
*/
private static List<String> getClassNameByJar(String jarPath, boolean childPackage) throws Exception {
List<String> myClassName = new ArrayList<String>();
String[] jarInfo = jarPath.split("!");
String jarFilePath = jarInfo[0].substring(jarInfo[0].indexOf("/"));
String packagePath = jarInfo[1].substring(1);
JarFile jarFile = null;
try {
jarFile = new JarFile(jarFilePath);
Enumeration<JarEntry> entrys = jarFile.entries();
while (entrys.hasMoreElements()) {
JarEntry jarEntry = entrys.nextElement();
String entryName = jarEntry.getName();
if (entryName.endsWith(".class")) {
if (childPackage) {
if (entryName.startsWith(packagePath)) {
entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf("."));
myClassName.add(entryName);
}
} else {
int index = entryName.lastIndexOf("/");
String myPackagePath;
if (index != -1) {
myPackagePath = entryName.substring(0, index);
} else {
myPackagePath = entryName;
}
if (myPackagePath.equals(packagePath)) {
entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf("."));
myClassName.add(entryName);
}
}
}
}
} catch (Exception e) {
throw e;
} finally {
if (null != jarFile) {
jarFile.close();
}
}
return myClassName;
}
/**
* 从所有jar中搜索该包,并获取该包下所有类
*
* @param urls
* URL集合
* @param packagePath
* 包路径
* @param childPackage
* 是否遍历子包
* @return 类的完整名称
* @throws Exception
*/
private static List<String> getClassNameByJars(URL[] urls, String packagePath, boolean childPackage)
throws Exception {
List<String> myClassName = new ArrayList<String>();
if (urls != null) {
for (int i = 0; i < urls.length; i++) {
URL url = urls[i];
String urlPath = url.getPath();
// 不必搜索classes文件夹
if (urlPath.endsWith("classes/")) {
continue;
}
String jarPath = urlPath + "!/" + packagePath;
myClassName.addAll(getClassNameByJar(jarPath, childPackage));
}
}
return myClassName;
}
}