测试实现标记器接口的所有枚举

时间:2018-07-08 15:58:24

标签: junit enums kotlin kotlintest

我有一个空接口interface HavingUniqueValues(val v: Int) {}和一些枚举,例如enum class EnumName(override val v: Int) : HavingUniqueValues

我希望每个枚举中的元素都具有唯一的v值,但我可能会键入错误的值。所以我需要测试。

  1. 是否可以创建一个测试,将接口实现手动保存为List,并检查List中的所有实现是否满足要求?
  2. 如果是:是否可以创建一个函数来返回指定程序包中所有实现的List,以便在测试中使用它?

3 个答案:

答案 0 :(得分:3)

看看Reflections库,这可能对您有帮助。

您应该能够获得% ./kk.py % more kk.log Traceback (most recent call last): File "./kk.py", line 16, in <module> subprocess.run([ "echo", "hello world"], check=True ) File "/usr/lib/python3.6/subprocess.py", line 418, in run output=stdout, stderr=stderr) subprocess.CalledProcessError: Command '['echo', 'hello world']' returned 的所有子类型:

HavingUniqueValues

现在,这将导致实现val subjects: Set<Class<out HavingUniqueValues>> = Reflections("your.package").getSubTypesOf(HavingUniqueValues::class.java) 的所有枚举类的集合。您可以迭代它们的所有值以了解它们是否唯一:

HavingUniqueValues

我在这里使用subjects.forEach { enumClass -> assertEquals( enumClass.enumConstants.size, enumClass.enumConstants.map(HavingUniqueValues::v).toSet().size ) } 删除了所有非不可变值。

这将通过测试:

toSet()

这不会通过测试:

enum class EnumName(override val v: Int) : HavingUniqueValues { ONE(1), TWO(2), THREE(3) }

答案 1 :(得分:1)

自从您用kotlintest标记问题以来,我已经将@egor的出色答案变成了KotlinTest副本n粘贴代码段。

class MyTest : StringSpec({

  "unique values" {

    val subjects: Set<Class<out HavingUniqueValues>> =
        Reflections("your.package").getSubTypesOf(HavingUniqueValues::class.java)

    subjects.forEach { enumClass ->
      enumClass.enumConstants.size shouldBe
          enumClass.enumConstants.map(HavingUniqueValues::v).toSet().size
    }
  }

})

答案 2 :(得分:1)

我尝试了接受的解决方案,但不适用于枚举。似乎Reflectons库不支持搜索自定义枚举,异常等的实现。至少使用以上答案中提供的默认配置。有很多链接和文档回答了为什么不起作用:

Why doesn't reflections.getSubTypesOf(Object.class) find enums?

https://github.com/ronmamo/reflections/issues/126

我能够使用Classgraph找到并测试类似的解决方案

以下是适用于枚举的示例代码:

try (ScanResult scanResult = new ClassGraph().enableAllInfo().whitelistPackages("package.with.your.enums").scan()) {
    ClassInfoList implementationsRefs = scanResult.getClassesImplementing("package.with.your.enums.yourInterfaceForEnums");
    List<Class<?>> implementations = implementationsRefs.loadClasses();
    //here goes your code that operates on "implementations"
}