Java自动生成testcase

package com.citi.sl.tlc.services.tlc.collateralDataProcess.util;

import java.io.BufferedWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

import org.apache.commons.lang.RandomStringUtils;

import com.google.common.collect.Lists;

public class TestCaseGenerator {

private static final String FILE_SUFFIX_LOWERCASE = ".java";
private static final String FILE_SUFFIX_UPPERCASE = ".JAVA";

public static void main(String[] args) {
generateTestCaseFiles("C:\\Users\\pz27063\\git\\xx\\src\\main\\java\\");
}

/**
* Example1 :
* C:\\Users\\pz27063\\git\\tradelifecycle\\TLCCommon\\CommonExtract\\src\\main\\java
* Example2 :
* C:\\Users\\pz27063\\git\\tradelifecycle\\TLCCommon\\CommonExtract\\src\\main\\java\\com\\citi\\sl\\tlc\\common\\extract\\jobs\\eurexeligible
*
* @param projectAbsolutePath
*/
public static void generateTestCaseFiles(String projectAbsolutePath) {
List<String> folderList = getAllSubFolders(Paths.get(projectAbsolutePath));
if (folderList.isEmpty()) {
System.out.println("folder not exist or no files.");
}

folderList.forEach(sourceDir -> {

Path sourcePath = Paths.get(sourceDir);
String testFolderStr = sourceDir.replace("\\src\\main", "\\src\\test");
Path createdTestFolderPath = createTestCaseFolder(Paths.get(testFolderStr));
createTestCaseFile(sourcePath, createdTestFolderPath);
});
}

public static List<String> getAllSubFolders(Path path) {
List<String> folders = new ArrayList<>();
try {
if (path.toFile().isDirectory()) {
folders.add(path.toFile().getAbsolutePath());
Files.list(path).forEach(f -> {
List<String> subFolders = getAllSubFolders(f);
folders.addAll(subFolders);
});
}
} catch (IOException e) {
exitProcess(e);
}
return folders;
}

private static Path createTestCaseFolder(Path createTargetPath) {
try {
if (notExists(createTargetPath)) {
return Files.createDirectories(createTargetPath);
}
} catch (IOException e) {
exitProcess(e);
}
return createTargetPath;

}

private static void createTestCaseFile(Path sourcePath, Path testFolderPath) {
try {
Files.list(sourcePath).forEach(sourceFilePath -> {
if (sourceFilePath.toFile().isFile() && (sourceFilePath.toString().endsWith(FILE_SUFFIX_UPPERCASE)
|| sourceFilePath.toString().endsWith(FILE_SUFFIX_LOWERCASE))) {
buildTestClass(sourceFilePath, testFolderPath);
}
});
} catch (IOException e) {
exitProcess(e);
}
}

private static void buildTestClass(Path sourceFilePath, Path targetFolder) {
String className = sourceFilePath.getFileName().toString().replace(FILE_SUFFIX_LOWERCASE, "");
try {
Path newTestFilePath = targetFolder.resolve(className + "Test" + FILE_SUFFIX_LOWERCASE);
if (notExists(newTestFilePath)) {

String javaPath = convertPathToPackageClass(sourceFilePath);
Class<?> sourceClass = getSourceClass(javaPath);

if (isJavaBean(sourceClass)) {
newTestFilePath = Files.createFile(newTestFilePath);
writeJavaBeanTestClass(sourceClass, newTestFilePath);
System.out.println("JavaBean :" + newTestFilePath.toString() + " created.");

} else if (isNotAbstract(sourceClass) && isNotInterface(sourceClass) && isNotEnum(sourceClass)) {
newTestFilePath = Files.createFile(newTestFilePath);
writeTestClass(sourceClass, newTestFilePath);
System.out.println(newTestFilePath.toString() + " created.");
}

}
} catch (IOException e) {
exitProcess(e);
}

}

private static void writeTestClass(Class<?> sourceClass, Path newTestFilePath) {

String className = sourceClass.getSimpleName();
Set<String> methodNames = getClassPublicMethods(sourceClass);
Map<String, Object> methodMap = getMethodMap(sourceClass);
String packageLine = sourceClass.getPackage().toString();

BufferedWriter writer = null;
try {
writer = Files.newBufferedWriter(newTestFilePath);
StringBuilder fileBuilder = new StringBuilder();

fileBuilder.append(packageLine + ";\n");
fileBuilder.append("\n");
String importPackage = "import org.mockito.InjectMocks;\r\n" + "import org.mockito.MockitoAnnotations;\r\n"
+ "import org.junit.Before;\r\n" + "import org.junit.Test;";
fileBuilder.append(importPackage);
fileBuilder.append("\n");
fileBuilder.append("public class " + className + "Test{\n");
fileBuilder.append("\n");
fileBuilder.append("\t");
fileBuilder.append("@InjectMocks\n");
fileBuilder.append("\t");
fileBuilder.append("private " + className + " "
+ className.substring(0, 1).toLowerCase().concat(className.substring(1)) + ";\n");

fileBuilder.append(getInitMethodString());

for (String methodName : methodNames) {
fileBuilder.append(generateTestMethod(methodName, methodMap));
}
fileBuilder.append("\n\n}");
writer.write(fileBuilder.toString());

} catch (IOException e) {
exitProcess(e);
} finally {
if (null != writer) {
try {
writer.close();
} catch (IOException e) {
exitProcess(e);
}
}
}

}

private static void writeJavaBeanTestClass(Class<?> sourceClass, Path newTestFilePath) {

String className = sourceClass.getSimpleName();
String packageLine = sourceClass.getPackage().toString();

BufferedWriter writer = null;
try {
writer = Files.newBufferedWriter(newTestFilePath);
StringBuilder fileBuilder = new StringBuilder();
fileBuilder.append(packageLine + ";\n");
fileBuilder.append("\n");
fileBuilder.append(generateJavaBeanTestClass(sourceClass.getPackage().getName(), className));
writer.write(fileBuilder.toString());

} catch (IOException e) {
exitProcess(e);
} finally {
if (null != writer) {
try {
writer.close();
} catch (IOException e) {
exitProcess(e);
}
}
}

}

private static String generateJavaBeanTestClass(String packageName, String className) {

String packageImport = "import java.beans.PropertyDescriptor;\r\n" + "import java.lang.reflect.Field;\r\n"
+ "import java.lang.reflect.Method;\r\n" + "\r\n" + "import org.junit.Before;\r\n"
+ "import org.junit.Test;\r\n" + "import org.mockito.InjectMocks;\r\n"
+ "import org.mockito.MockitoAnnotations;\n";

String classBodyStart = "public class " + className + "Test{\n";

String method = " \r\n" + " @InjectMocks\r\n" + " private " + className + " "
+ className.substring(0, 1).toLowerCase().concat(className.substring(1, className.length())) + ";\r\n"
+ "\r\n" + " @Before\r\n" + " public void initMocks(){\r\n"
+ " MockitoAnnotations.initMocks(this);\r\n" + " }\r\n" + " @Test\r\n"
+ " public void testSetGetMethod() {\r\n" + " try {\r\n"
+ " Class<?> clazz = Class.forName(\"" + packageName + "." + className + "\");\r\n"
+ " Object obj = clazz.newInstance();\r\n"
+ " Field[] fields = clazz.getDeclaredFields();\r\n"
+ " for (Field f : fields) {\r\n" + " try {\r\n"
+ " PropertyDescriptor pd = new PropertyDescriptor(f.getName(), clazz);\r\n"
+ " Method writeMethod = pd.getWriteMethod();\r\n"
+ " writeMethod.invoke(obj, new Object[] { null });\r\n"
+ " Method readMethod = pd.getReadMethod();\r\n"
+ " readMethod.invoke(obj);\r\n" + " } catch (Exception e) {\r\n"
+ " System.out.println(e);\r\n" + " }\r\n" + " }\r\n"
+ " } catch (Exception e) {\r\n" + " System.out.println(e);\r\n" + " }\r\n" + "\r\n"
+ " }";

String classBodyEnd = "}";

StringBuilder builder = new StringBuilder();
builder.append(packageImport);
builder.append("\n\n");
builder.append(classBodyStart);
builder.append(method);
builder.append(classBodyEnd);
return builder.toString();
}

private static boolean isJavaBean(Class<?> sourceClass) {
String fullPackage = sourceClass.getPackage().getName().toLowerCase();
return (fullPackage.endsWith(".bean") || fullPackage.endsWith(".entity") || fullPackage.endsWith(".beans")
|| fullPackage.endsWith(".entities"));
}

private static String generateTestMethod(String methodName, Map<String, Object> methodMap) {
StringBuilder methodBuilder = new StringBuilder();
String className = (String) methodMap.get("className");
Object[] methodObj = (Object[]) methodMap.get(methodName);

Class<?> returnType = (Class<?>) methodObj[0];
Class[] paramTypes = (Class[]) methodObj[1];

List<Class<?>> paramTypeList = Arrays.asList(paramTypes);
List<String> paramTypeParam = Lists.newArrayList();

List<String> stringList = Lists.newArrayList("String");
List<String> intList = Lists.newArrayList("int", "Integer");
List<String> longList = Lists.newArrayList("Long", "long");
List<String> doubleList = Lists.newArrayList("Double", "double");
List<String> shortList = Lists.newArrayList("Short", "short");
List<String> floatList = Lists.newArrayList("Float", "float");
List<String> booleanList = Lists.newArrayList("boolean");
List<String> charList = Lists.newArrayList("Char", "char");
List<String> byteList = Lists.newArrayList("Byte", "byte");

for (Class<?> paramClass : paramTypeList) {

// String paramClsStr = paramClass.getSimpleName().toUpperCase();
String paramClsStr = paramClass.getSimpleName();

if (stringList.contains(paramClsStr)) {
paramTypeParam.add("\"" + RandomStringUtils.randomAlphabetic(3) + "\"");
} else if (intList.contains(paramClsStr)) {
paramTypeParam.add("0");
} else if (longList.contains(paramClsStr)) {
paramTypeParam.add("1L");
} else if (doubleList.contains(paramClsStr)) {
paramTypeParam.add("1D");
} else if (shortList.contains(paramClsStr)) {
paramTypeParam.add("1");
} else if (floatList.contains(paramClsStr)) {
paramTypeParam.add("1F");
} else if (booleanList.contains(paramClsStr)) {
paramTypeParam.add("true");
} else if (charList.contains(paramClsStr)) {
paramTypeParam.add("\'A\'");
} else if (byteList.contains(paramClsStr)) {
paramTypeParam.add("10");
} else {
if (paramClsStr instanceof Object && !paramClass.isEnum() && !paramClass.isInterface()
&& !paramClass.isArray()) {
paramTypeParam.add("new " + paramClass.getName() + "()");
} else {
paramTypeParam.add("null");
}
}
}

String paramStr = String.join(",", paramTypeParam);

String returnCode = "";
String returnClassName = returnType.getSimpleName();
if (!returnClassName.equals("void")) {
returnCode = returnType.getName() + " result = ";
}

String methodBody = "\t@Test\r\n" + " public void test"
+ methodName.substring(0, 1).toUpperCase().concat(methodName.substring(1)) + "(){\r\n" + "\t\ttry{\r\n"
+ "\t\t\t" + returnCode
+ className.substring(0, 1).toLowerCase().concat(className.substring(1, className.length())) + "."
+ methodName + "(" + paramStr + ");\r\n" + "\t\t}catch (Exception e) {\n\t\t}\n" + "\n\t}\n\n";

methodBuilder.append(methodBody);
return methodBuilder.toString();
}

private static String getInitMethodString() {
StringBuilder methodBuilder = new StringBuilder();
methodBuilder.append("\n");
methodBuilder.append("\t@Before\n");
methodBuilder.append("\t");
methodBuilder.append("public void initMocks(){\n");
methodBuilder.append("\t\tMockitoAnnotations.initMocks(this);\n");
methodBuilder.append("\t}");
methodBuilder.append("\n");
return methodBuilder.toString();
}

private static String convertPathToPackageClass(Path sourcePath) {
String fileName = "";
fileName = sourcePath.getFileName().toString().replace(".java", "");
String packageName = getPackageName(sourcePath);
return packageName + "." + fileName;
}

private static String getPackageName(Path sourcePath) {
try {
Optional<String> optional = Files.lines(sourcePath).findFirst();
if (optional.isPresent()) {
return optional.get().replace("package ", "").replace(";", "");
}
} catch (IOException e) {
exitProcess(e);
}
return "";
}

private static boolean isNotAbstract(Class<?> cls) {
return !Modifier.isAbstract(cls.getModifiers());
}

private static boolean isNotInterface(Class<?> cls) {
return !Modifier.isInterface(cls.getModifiers());
}

private static boolean isNotEnum(Class<?> cls) {
return !cls.isEnum();
}

private static Set<String> getClassPublicMethods(Class<?> cls) {
Set<String> methodSet = new HashSet<>();
Method[] publicMethods = cls.getDeclaredMethods();
for (Method m : publicMethods) {
if (Modifier.isPublic(m.getModifiers()) || Modifier.isProtected(m.getModifiers())) {
methodSet.add(m.getName());
}
}

return methodSet;
}

private static Map<String, Object> getMethodMap(Class<?> cls) {
Map<String, Object> methodMap = new HashMap<>();
Method[] publicMethods = cls.getDeclaredMethods();
for (Method m : publicMethods) {
if (Modifier.isPublic(m.getModifiers()) || Modifier.isProtected(m.getModifiers())) {
// Return type
Class<?> returnType = m.getReturnType();
// Method parameter
Class[] paramTypes = m.getParameterTypes();
Object[] methodObj = new Object[] { returnType, paramTypes };
methodMap.put(m.getName(), methodObj);
}
}

methodMap.put("className", cls.getSimpleName());

return methodMap;
}

private static Class<?> getSourceClass(String className) {
Class<?> cls = null;
try {
cls = Class.forName(className);
} catch (ClassNotFoundException e) {
exitProcess(e);
}
return cls;
}

private static void exitProcess(Exception e) {
e.printStackTrace();
System.exit(-1);
}

private static boolean notExists(Path path) {
return !exists(path);
}

private static boolean exists(Path path) {
return path.toFile().exists();
}
}

posted on 2019-07-03 15:40  长方形  阅读(673)  评论(0编辑  收藏  举报

导航