首页 > 解决方案 > 使用 @ParameterizedTest 和 @MethodSource 或 @ValueSource 为多个类运行相同的 JUnit 测试

问题描述

我正在创建一个排序算法库。每个类都有相同的方法:

public static <T extends Comparable<? super T>> void sort(T[] array)

我会让所有类都实现一个接口或扩展一个抽象类,但sort方法是static这意味着它不能被覆盖。

这是我第一次使用 JUnit 5。我想在所有排序类上运行相同的 JUnit 测试。经过一些研究,似乎在 JUnit 5 中执行此操作的方法是使用@ParameterizedTest. 我正在考虑的方式是在测试方法中获取类作为参数,sort使用反射获取方法,然后调用它。问题是,我似乎在将课程传递给测试时遇到了问题。当我@ParameterizedTest@ValueSourceor 一起使用时@MethodSource,参数中的Classin 类型为 java.lang.Class

只是为了测试使用@ParameterizedTest,我尝试了以下方法:

@ParameterizedTest
@MethodSource("sortClasses")
public void simpleParameterizedTest(Class<?> sortClass) {
   System.out.println(sortClass.getClass().getName());
}

private static Class<?>[] sortClasses() {
    return new Class<?>[] {
        BubbleSort.class
    };
}

@ParameterizedTest
@ValueSource(classes = {BubbleSort.class})
public void simpleParameterizedTest(Class<?> sortClass) {
    System.out.println(sortClass.getClass().getName());
}

两者都打印:java.lang.Class而不是my.package.BubbleSort.

我还没有尝试过,但我知道我可以使用带有类String名的反射来获取类,但这似乎有点矫枉过正。

我错过了什么?这是 JUnit 5 中最好的方法吗?

标签: javagenericsjunitreflectionjunit5

解决方案


将解决评论移至答案:

getClass()是一种方法,它出现在所有 java 上Object,告诉你class那个Object。由于 yoursortClass Object 本身就是a Class Object,因此调用getClass()它会导致Class. 相反,您可以简单地调用sortClass.getName(),它为您提供sortClass自身的名称。


TL;博士:

替换sortClass.getClass().getName()sortClass.getName()。:)


推荐阅读