在一个非常庞大的项目中,有很多ExceptionClasses,其中异常细节被实现为enum
。
NAME_OF_EXCEPTION_DETAIL(ID, PRIORITY)
e.g:
NO_LICENSE_FOUND(100, 0)
UNSUPPORTED_LICENSE(101, 1)
WRONG_LICENSE_FOR_VERSION(101, 0)
在某些情况下,异常详细信息ID是相同的,应该永远不会发生。很可能有更多的重复,但这个项目是巨大的手工检查...
是否有一种智能方法可以检查重复代码,例如UnitTesting - 从未使用它。
感谢您的帮助!
编辑(当只使用一个枚举时,Bens答案是解决此问题的好方法): 为了更清楚我的具体任务,这就是情况。 编写了许多用于处理ExceptionDetails的类,例如
TopicOneExceptionDetails.java
TopicTwoExceptionDetails.java (and so on)
这些类中的每一个都定义了这个主题的枚举,如下所示:
public enum TopicOneExceptionDetails implements ApplicationException.ExceptionDetails { .... }
然后声明与TopicOne错误相关的错误,例如
SETTING_TIMEZONE_FAILED(55, ...)
Setting_DATETIME_FAILED(56, ...)
在TopicOne的这个枚举中,每个错误ID都必须是唯一的。但是例如ID 55(此处用于SETTING_TIMEZONE_FAILED)可用于声明与TopicTwo相关的错误而没有问题。
编辑2 (使用反射?)
我找到了一个由pretty informative answer编写的关于java Reflections
的{{3}}。我认为这可以解决我的问题。我需要休息但我会报告回来。我目前的想法是:
Reflections reflections = new Reflections("project.de")
for(Class<? extends ApplicationException.ExceptionDetails> exceptionDetailsClasses : reflections.getSubTypesOf(ApplicationException.ExceptionDetails.class)){
for ( ... ) .. }
我应该可以查看ID,例如像Ben建议的那样。我稍后会报告。
编辑3 (问题已解决!)
与编辑2中描述的一样,我可以使用reflections
轻松解决此问题。
public class ApplicationExceptionDetailsErrorCodeValidationTest {
@Test
public void validateErrorCodeUniqueness() throws ErrorCodeUniquenessBroken{
Reflections reflections = new Reflections("de.xyz");
for (Class<? extends ApplicationException.ExceptionDetails> exceptionDetailsClass : reflections.getSubTypesOf(ApplicationException.ExceptionDetails.class)) {
if (exceptionDetailsClass.getSimpleName().equals("TestExceptionDetails")) {
continue;
}
List<Integer> errorCodes = new ArrayList<Integer>();
for (ApplicationException.ExceptionDetails exceptionDetails : exceptionDetailsClass.getEnumConstants()) {
if (errorCodes.contains(exceptionDetails.getErrorCode().getId())) throw new ErrorCodeUniquenessBroken("ErrorCode uniqueness broken! ErrorCode: " + exceptionDetails.getMessageKey() + " has repeated ErrorCode! Change it!");
else errorCodes.add(exceptionDetails.getErrorCode().getId());
}
}
} }
特别感谢Ben和Spotted的努力。两者都回答了一些非常好的例子,说明如何解决一般的主题问题。在我的情况下,它有点复杂。
答案 0 :(得分:6)
单程检查您的Enum是否有重复ID(未经过测试,但应该可以使用)。
您可以将此代码的一部分用于单元测试(或单独使用):
import java.util.HashSet;
import java.util.Set;
public class NewClass
{
public static enum Errors
{
ERROR_A(1),
ERROR_B(2),
ERROR_C(3),
ERROR_D(2), //duplicate is here!
ERROR_E(5);
int m_id;
Errors(int id)
{
m_id = id;
}
public int getId()
{
return m_id;
}
}
public static void main(String[] args)
{
Set<Integer> usedIds = new HashSet<>();
for (Errors e : Errors.values()) //iterate over all Error-Enum-Items
{
int id = e.getId(); //fetch id from enum-item
if (usedIds.contains(id)) //check if id was used before
System.err.println("ID ALREADY USED: " + e.name() + ":" + id);
else
usedIds.add(id); //remember new used id here
}
}
}
干杯!
答案 1 :(得分:2)
当然,单位测试是检测(有确定)此类问题的好方法。
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.Test;
public class ErrorSpec {
@Test
public void itShouldNotHaveTwoEnumsWithSameId() {
Set<Integer> idsWithoutDuplicates = Arrays.stream(Error.values())
.map(Error::getId)
.collect(Collectors.toSet());
assertEquals(Error.values().length, idsWithoutDuplicates.size());
}
}
如果您希望使用AssertJ,可以使测试更加明确(并指出哪个ID重复!):
import static org.assertj.core.api.Assertions.*;
import java.util.Arrays;
import org.junit.Test;
public class ErrorSpec {
@Test
public void itShouldNotHaveTwoEnumsWithSameId() {
int[] ids = Arrays.stream(Error.values())
.mapToInt(Error::getId)
.toArray();
assertThat(ids).doesNotHaveDuplicates();
}
}