package org.test4j.junit.parametermethod; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.test4j.junit.annotations.DataFrom; import org.test4j.module.core.utility.MessageHelper; import org.test4j.tools.commons.MethodHelper; import org.test4j.tools.commons.Reflector; import org.test4j.tools.exception.NewInstanceException; import org.test4j.tools.exception.NoSuchMethodRuntimeException; @SuppressWarnings({ "rawtypes", "unchecked" }) public class ParameterDataFromHelper { /** * 构造一系列有参的测试方法 * * @param testClazz 当前测试类class * @param testMethod 测试方法 * @param dataFrom * @return */ public static List<FrameworkMethodWithParameters> computeParameterizedTestMethods(Class testClazz, Method testMethod, DataFrom dataFrom) { String fromMethod = dataFrom.value(); if ("".equals(fromMethod)) { throw new RuntimeException("You should specify the value property of @DataFrom() item."); } switch (dataFrom.source()) { case FromMethod: Class dataFromClaz = dataFrom.clazz(); if (dataFromClaz == DataFrom.class) { dataFromClaz = testMethod.getDeclaringClass(); } return computeParameterziedFromDataProviderMethod(testClazz, testMethod, fromMethod, dataFromClaz); case FromFile: // TODO default: throw new RuntimeException("umimplement the data from uri mode."); } } private static List<FrameworkMethodWithParameters> computeParameterziedFromDataProviderMethod(Class testClazz, Method testMethod, String dataFromMethod, Class dataFromClaz) { Object data = getDataFromMethod(dataFromMethod, testClazz, dataFromClaz); if (data instanceof Iterator) { return computeParameterFromIterator(testMethod, (Iterator) data); } else if (data instanceof Object[][]) { return computeParameterFromArray(testMethod, (Object[][]) data); } else { throw new RuntimeException( "The @DataFrom method can only return value of type Iterator<Object[]> or Object[][]."); } } private static Object getDataFromMethod(String dataFromMethod, Class testClazz, Class dataFromClaz) { try { if (dataFromClaz.isAssignableFrom(testClazz)) { Object from = Reflector.instance.newInstance(testClazz); Object data = MethodHelper.invokeUnThrow(from, dataFromMethod); return data; } else { Object from = Reflector.instance.newInstance(dataFromClaz); Object data = MethodHelper.invokeUnThrow(from, dataFromMethod); return data; } } catch (NewInstanceException e1) { try { Object data = MethodHelper.invokeStatic(dataFromClaz, dataFromMethod); return data; } catch (NoSuchMethodRuntimeException e2) { String err = "The @DataFrom method isn't a static method or isn't declared in a concrete class."; MessageHelper.error(err, e1, e2); throw new RuntimeException(err, e2); } } } private static List<FrameworkMethodWithParameters> computeParameterFromIterator(Method method, Iterator iterator) { List<FrameworkMethodWithParameters> methodWithParameters = new ArrayList<FrameworkMethodWithParameters>(); for (; iterator.hasNext();) { Object caseData = iterator.next(); if (caseData instanceof Object[]) { methodWithParameters.add(new FrameworkMethodWithParameters(method, (Object[]) caseData)); } else { methodWithParameters.add(new FrameworkMethodWithParameters(method, new Object[] { caseData })); } } return methodWithParameters; } private static List<FrameworkMethodWithParameters> computeParameterFromArray(Method method, Object[][] array) { List<FrameworkMethodWithParameters> methodWithParameters = new ArrayList<FrameworkMethodWithParameters>(); for (Object[] caseData : array) { methodWithParameters.add(new FrameworkMethodWithParameters(method, (Object[]) caseData)); } return methodWithParameters; } }