Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Eclipse Testrunner中使用名称进行参数化测试_Java_Eclipse_Unit Testing_Junit_Parameterized Unit Test - Fatal编程技术网

Java 在Eclipse Testrunner中使用名称进行参数化测试

Java 在Eclipse Testrunner中使用名称进行参数化测试,java,eclipse,unit-testing,junit,parameterized-unit-test,Java,Eclipse,Unit Testing,Junit,Parameterized Unit Test,当您使用EclipseTestRunner运行JUnit4参数化测试时,图形表示相当愚蠢:对于每个测试,您都有一个名为[0],[1]等的节点。 是否可以为测试[0],[1]等提供明确的名称?为测试实现toString方法似乎没有帮助 (这是一个后续问题。)我认为JUnit4中没有内置任何东西可以做到这一点 我已经实现了一个解决方案。我在现有的基础上构建了自己的参数化类: public class MyParameterized extends TestClassRunner { @Ret

当您使用EclipseTestRunner运行JUnit4参数化测试时,图形表示相当愚蠢:对于每个测试,您都有一个名为
[0]
[1]
等的节点。 是否可以为测试
[0]
[1]
等提供明确的名称?为测试实现
toString
方法似乎没有帮助

(这是一个后续问题。)

我认为JUnit4中没有内置任何东西可以做到这一点

我已经实现了一个解决方案。我在现有的基础上构建了自己的
参数化
类:

public class MyParameterized extends TestClassRunner {
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public static @interface Parameters {
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public static @interface Name {
    }

    public static Collection<Object[]> eachOne(Object... params) {
        List<Object[]> results = new ArrayList<Object[]>();
        for (Object param : params)
            results.add(new Object[] { param });
        return results;
    }

    // TODO: single-class this extension

    private static class TestClassRunnerForParameters extends TestClassMethodsRunner {
        private final Object[] fParameters;

        private final Class<?> fTestClass;

        private Object instance;

        private final int fParameterSetNumber;

        private final Constructor<?> fConstructor;

        private TestClassRunnerForParameters(Class<?> klass, Object[] parameters, int i) throws Exception {
            super(klass);
            fTestClass = klass;
            fParameters = parameters;
            fParameterSetNumber = i;
            fConstructor = getOnlyConstructor();
            instance = fConstructor.newInstance(fParameters);
        }

        @Override
        protected Object createTest() throws Exception {
            return instance;
        }

        @Override
        protected String getName() {
            String name = null;
            try {
                Method m = getNameMethod();
                if (m != null)
                    name = (String) m.invoke(instance);
            } catch (Exception e) {
            }
            return String.format("[%s]", (name == null ? fParameterSetNumber : name));
        }

        @Override
        protected String testName(final Method method) {
            String name = null;
            try {
                Method m = getNameMethod();
                if (m != null)
                    name = (String) m.invoke(instance);
            } catch (Exception e) {
            }
            return String.format("%s[%s]", method.getName(), (name == null ? fParameterSetNumber : name));
        }

        private Constructor<?> getOnlyConstructor() {
            Constructor<?>[] constructors = getTestClass().getConstructors();
            assertEquals(1, constructors.length);
            return constructors[0];
        }

        private Method getNameMethod() throws Exception {
            for (Method each : fTestClass.getMethods()) {
                if (Modifier.isPublic((each.getModifiers()))) {
                    Annotation[] annotations = each.getAnnotations();
                    for (Annotation annotation : annotations) {
                        if (annotation.annotationType() == Name.class) {
                            if (each.getReturnType().equals(String.class))
                                return each;
                            else
                                throw new Exception("Name annotated method doesn't return an object of type String.");
                        }
                    }
                }
            }
            return null;
        }
    }

    // TODO: I think this now eagerly reads parameters, which was never the
    // point.

    public static class RunAllParameterMethods extends CompositeRunner {
        private final Class<?> fKlass;

        public RunAllParameterMethods(Class<?> klass) throws Exception {
            super(klass.getName());
            fKlass = klass;
            int i = 0;
            for (final Object each : getParametersList()) {
                if (each instanceof Object[])
                    super.add(new TestClassRunnerForParameters(klass, (Object[]) each, i++));
                else
                    throw new Exception(String.format("%s.%s() must return a Collection of arrays.", fKlass.getName(), getParametersMethod().getName()));
            }
        }

        private Collection<?> getParametersList() throws IllegalAccessException, InvocationTargetException, Exception {
            return (Collection<?>) getParametersMethod().invoke(null);
        }

        private Method getParametersMethod() throws Exception {
            for (Method each : fKlass.getMethods()) {
                if (Modifier.isStatic(each.getModifiers())) {
                    Annotation[] annotations = each.getAnnotations();
                    for (Annotation annotation : annotations) {
                        if (annotation.annotationType() == Parameters.class)
                            return each;
                    }
                }
            }
            throw new Exception("No public static parameters method on class " + getName());
        }
    }

    public MyParameterized(final Class<?> klass) throws Exception {
        super(klass, new RunAllParameterMethods(klass));
    }

    @Override
    protected void validate(MethodValidator methodValidator) {
        methodValidator.validateStaticMethods();
        methodValidator.validateInstanceMethods();
    }

}
公共类MyParameterized扩展TestClassRunner{
@保留(RetentionPolicy.RUNTIME)
@目标(ElementType.METHOD)
公共静态@接口参数{
}
@保留(RetentionPolicy.RUNTIME)
@目标(ElementType.METHOD)
公共静态@接口名{
}
公共静态集合eachOne(对象…参数){
列表结果=新建ArrayList();
用于(对象参数:参数)
添加(新对象[]{param});
返回结果;
}
//TODO:单类此扩展
私有静态类TestClassRunnerForParameters扩展TestClassMethodsRunner{
私有最终对象[]fParameters;
私人期末班FTEST班;
私有对象实例;
专用最终int fParameterSetNumber;
私人最终建造商fConstructor;
私有TestClassRunnerForParameters(类klass,对象[]参数,int i)引发异常{
超级(klass);;
fTestClass=klass;
F参数=参数;
fParameterSetNumber=i;
fConstructor=getOnlyConstructor();
instance=fConstructor.newInstance(fParameters);
}
@凌驾
受保护对象createTest()引发异常{
返回实例;
}
@凌驾
受保护的字符串getName(){
字符串名称=null;
试一试{
方法m=getNameMethod();
如果(m!=null)
name=(字符串)m.invoke(实例);
}捕获(例外e){
}
返回String.format(“[%s]”,name==null?fParameterSetNumber:name));
}
@凌驾
受保护的字符串testName(最终方法){
字符串名称=null;
试一试{
方法m=getNameMethod();
如果(m!=null)
name=(字符串)m.invoke(实例);
}捕获(例外e){
}
返回String.format(“%s[%s]”,method.getName(),(name==null?fParameterSetNumber:name));
}
私有构造函数getOnlyConstructor(){
构造函数[]构造函数=getTestClass().getConstructors();
assertEquals(1,施工人员、长度);
返回构造函数[0];
}
私有方法getNameMethod()引发异常{
对于(每个方法:fTestClass.getMethods()){
if(Modifier.isPublic((each.getModifiers())){
Annotation[]annotations=each.getAnnotations();
用于(注释:注释){
if(annotation.annotationType()==Name.class){
if(each.getReturnType().equals(String.class))
返回每个;
其他的
抛出新异常(“名称注释的方法不返回String类型的对象”);
}
}
}
}
返回null;
}
}
//TODO:我想现在这个程序急切地读取参数,而这从来都不是最好的
//重点。
公共静态类RunAllParameterMethods扩展了CompositeRunner{
私人期末班;
公共RunAllParameterMethods(类klass)引发异常{
super(klass.getName());
FCLASS=klass;
int i=0;
对于(每个最终对象:getParametersList()){
if(对象[]的每个实例)
添加(新的TestClassRunnerForParameters(klass,(Object[]),每个,i++);
其他的
抛出新异常(String.format(“%s.%s()必须返回数组集合”)、FClass.getName()、getParametersMethod().getName());
}
}
私有集合getParametersList()引发IllegaAccessException、InvocationTargetException、Exception{
return(Collection)getParametersMethod().invoke(null);
}
私有方法getParametersMethod()引发异常{
对于(每个方法:fKlass.getMethods()){
if(Modifier.isStatic(each.getModifiers())){
Annotation[]annotations=each.getAnnotations();
用于(注释:注释){
if(annotation.annotationType()==Parameters.class)
返回每个;
}
}
}
抛出新异常(“类上没有公共静态参数方法”+getName());
}
}
公共MyParameterized(最终类klass)引发异常{
super(klass,新的RunAllParameterMethods(klass));
}
@凌驾
受保护的无效验证(MethodValidator MethodValidator){
methodValidator.validateStaticMethods();
methodValidator.validateInstanceMethods();
}
}
使用方式如下:

@RunWith(MyParameterized.class)
public class ParameterizedTest {
    private File file;
    public ParameterizedTest(File file) {
        this.file = file;
    }

    @Test
    public void test1() throws Exception {}

    @Test
    public void test2() throws Exception {}

    @Name
    public String getName() {
        return "coolFile:" + file.getName();
    }

    @Parameters
    public static Collection<Object[]> data() {
        // load the files as you want
        Object[] fileArg1 = new Object[] { new File("path1") };
        Object[] fileArg2 = new Object[] { new File("path2") };

        Collection<Object[]> data = new ArrayList<Object[]>();
        data.add(fileArg1);
        data.add(fileArg2);
        return data;
    }
}
@RunWith(MyParameterized.class)
公共类参数化测试{
私有文件;
公共参数化测试(文件){
this.file=文件;
}
@试验
public void test1()引发异常{}
@试验
public void test2()引发异常{}
@名字
公共字符串getName(){
重新
assertEquals("Not the expected decision for the senator " + this.currentSenatorName + " and the law " + this.votedLaw, 
expectedVote, actualVote);
@Parameters(name = "{index}: fib({0})={1}")
public static Iterable<Object[]> data() {
    return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 },
            { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } });
}
@Test
@Parameters({ "1,1", "2,2", "3,6" })
@TestCaseName("factorial({0}) = {1}")
public void custom_names_for_test_case(int argument, int result) { }
@Test
@Parameters({ "value1, value2", "value3, value4" })
@TestCaseName("[{index}] {method}: {params}")
public void predefined_macro_for_test_case_name(String param1, String param2) { }