我的项目中有几个枚举类。为了维护持久性,我们不依赖内部ID,因为内部ID随枚举值的顺序而变化(例如,当稍后在两者之间的某个位置添加新枚举时)。而是将(通常是数字的)id属性分配给每个值。
但这打开了另一个错误可能性:同一个ID可以分配两次。因此,我创建了一个JUnit测试,该测试检查所有值的ID是否重复。而且我想使该测试通用,以避免为每个新的枚举类复制粘贴。带有枚举类和用于持续性的getter并运行测试的东西,例如:
(new JUnitEnumTester(OneEnum.class, getId)).runTest()
(new JUnitEnumTester(TwoEnum.class, getName)).runTest()
到目前为止,我要做的是对单个枚举类的测试:
package com.xyz.enums;
import static org.junit.Assert.*;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
public class OneTest {
@Test
// Testing enum IDs
public void testUniqueId_WithMap() {
Map<Integer,String> idMap = new HashMap<Integer,String>();
String msg = "";
for (One elem : One.values()) {
Integer enumId = new Integer(elem.getId());
if (idMap.containsKey(enumId)) {
msg += "\nDuplicate ID found: '" + enumId.toString() +
"' for enum: " + idMap.get(enumId) + ", " + elem.name();
}
else {
idMap.put(enumId, elem.name());
}
}
if (msg.length() > 0) {
fail(msg);
}
}
}
问题是,如何概括这种方法?
首先,我要使用静态方法,但无法弄清楚如何引用该方法用作吸气剂。
public class JUnitTester {
static public void runTest(Class cls, ? method) {
:
}
}
我认为这还是行不通的,所以我现在正在使用泛型。尽管它似乎更面向对象,但仍然不能滚动。
public class JunitEnumTester <? extends Enum> {
public void runTest() {
Map<Integer,String> idMap = new HashMap<Integer,String>();
String msg = "";
for (Enum elem : Enum.values()) {
Integer enumId = new Integer(elem.getId());
if (idMap.containsKey(enumId)) {
msg += "\nDuplicate ID: '" + enumId.toString() +
"' for " + idMap.get(enumId) + ", " + elem.name();
}
else {
idMap.put(enumId, elem.name());
}
}
if (msg.length() > 0) {
fail(msg);
}
}
}
有什么提示或路线指示吗?
答案 0 :(得分:0)
要重用您的方法,我们需要对其进行概括。我们需要枚举值,我们可以调用枚举值来获取相应的ID。这两个依赖项应作为参数传递。
枚举类型T
的枚举值可以作为数组T[]
传递。要获取枚举的ID,我们可以使用Function<T, ID> idExtractor
,它采用类型为T
的枚举值,并返回其类型为ID
的ID。
方法如下:
public static <T extends Enum<T>, ID> void testUniqueIds(T[] enumValues, Function<T, ID> idExtractor) {
String msg = "";
Map<ID, T> enumsById = new HashMap<>();
for (T enumValue : enumValues) {
ID id = idExtractor.apply(enumValue);
if (enumsById.containsKey(id)) {
msg += "\nDuplicate ID found: '" + id.toString() + "' for enum: " + enumsById.get(id) + ", " + enumValue.name();
} else {
enumsById.put(id, enumValue);
}
}
if (!msg.isEmpty()) {
fail(msg);
}
}
让我们看一个小例子:
enum ABC {
A('a'), B('b'), C('c');
private char letter;
private ABC(char letter) {
this.letter = letter;
}
public char getLetter() {
return letter;
}
}
对应的测试方法:
@Test
void testABC() {
JunitEnumTester.testUniqueIds(ABC.values(), ABC::getLetter);
}
要传递枚举值,我们使用在每个枚举上定义的方法values()
。为了传递id提取器函数,我们使用一个方法引用,该引用使调用简短。
如果我们运行测试,它将为绿色。但是,如果我们使用字母C
初始化枚举常量'a'
,则测试将失败。