有关如何在Java代码中检查非唯一ID的一般信息
在一个非常庞大的项目中,有许多异常类,其中异常详细信息以有关如何在Java代码中检查非唯一ID的一般信息,java,unit-testing,Java,Unit Testing,在一个非常庞大的项目中,有许多异常类,其中异常详细信息以enum的形式实现 NAME_OF_EXCEPTION_DETAIL(ID, PRIORITY) e、 g: 在某些情况下,异常详细信息ID是相同的,不应该发生。这是相当该死的可能,有更多的重复,但这个项目是巨大的,以检查这一手 是否有一种聪明的方法来检查代码是否重复,例如单元测试-以前从未使用过它 谢谢你的帮助 编辑(当只使用一个枚举时,Bens答案是解决此问题的好方法): 更清楚地说,在我的具体任务中,这就是情况。 有很多类是用来处理
enum
的形式实现
NAME_OF_EXCEPTION_DETAIL(ID, PRIORITY)
e、 g:
在某些情况下,异常详细信息ID是相同的,不应该发生。这是相当该死的可能,有更多的重复,但这个项目是巨大的,以检查这一手
是否有一种聪明的方法来检查代码是否重复,例如单元测试-以前从未使用过它
谢谢你的帮助
编辑(当只使用一个枚举时,Bens答案是解决此问题的好方法):
更清楚地说,在我的具体任务中,这就是情况。
有很多类是用来处理异常细节的,例如
TopicOneExceptionDetails.java
TopicTwoExceptionDetails.java (and so on)
每个类都为此主题定义了一个枚举,如下所示:
public enum TopicOneExceptionDetails implements ApplicationException.ExceptionDetails { .... }
然后是与TopicOne错误相关的错误声明,例如
SETTING_TIMEZONE_FAILED(55, ...)
Setting_DATETIME_FAILED(56, ...)
在此TopicOne的枚举中,每个错误ID都必须是唯一的。但例如,ID55(此处用于设置_TIMEZONE_FAILED)可以毫无问题地用于与TopicTwo相关的错误声明
编辑2(使用反射?)
我找到了一本关于javaReflections
的书,作者是。我想这可以解决我的问题。我需要休息一下,但我会回来报告的。我目前的想法是:
Reflections reflections = new Reflections("project.de")
for(Class<? extends ApplicationException.ExceptionDetails> exceptionDetailsClasses : reflections.getSubTypesOf(ApplicationException.ExceptionDetails.class)){
for ( ... ) .. }
}
}
特别感谢Ben和Spotted的努力。两人都用一些很好的例子回答了如何解决一般的主题问题。在我的例子中,它只是变得有点复杂。一种检查枚举中重复ID的方法(它没有经过测试,但应该可以工作)。
您可以将部分代码用于单元测试(或单独使用):
import java.util.HashSet;
导入java.util.Set;
公共类新类
{
公共静态枚举错误
{
错误_A(1),
错误_B(2),
错误_C(3),
错误\u D(2),//重复项在这里!
误差(5);
国际货币基金组织;
错误(int-id)
{
m_id=id;
}
公共int getId()
{
返回m_id;
}
}
公共静态void main(字符串[]args)
{
Set usedIds=new HashSet();
for(Errors e:Errors.values())//迭代所有错误枚举项
{
int id=e.getId();//从枚举项获取id
if(usedIds.contains(id))//检查以前是否使用过id
System.err.println(“ID已被使用:”+e.name()+“:”+ID);
其他的
usedIds.add(id);//记住这里新使用的id
}
}
}
干杯 当然,单元测试是检测(有把握地)此类问题的好方法
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());
}
}
在枚举构造函数中,可以对静态表执行检查。这很有趣,谢谢。这应该是什么样子?有很多ExptionClass在其特定的例外中有自己的例外ID。那么,与一个静态表相比,会产生多个静态表吗?如果我想一想,我很确定我必须在每个expectiondetails调用中实现这个检查-对吗?你的意思是有许多不同的枚举?看看我的答案,也许它可以帮助…嗨Ben,谢谢你的回答。我明白这一点,喜欢这个想法。事实上,exeptiondetail类太多了,要找到它们需要大量的工作。另一个问题是,如果exceptiondetails类与另一个具有相同id的类不同,则允许它具有相同的id。到目前为止,我发现所有exceptiondetails类都继承自抽象类applicationexception,我可以在其中检查它?我不知道。你想在你的问题中再添加一些示例代码吗?我真的无法想象它是如何实现的。一个枚举不能从其他枚举继承。谢谢你,很高兴知道单元测试可以让我走得更远。但我不确定我是否理解你的例子。如果我这样说,检查ID的枚举地址在哪里?@Chrizzldi第一行从
Error
中检索所有ID,并将它们存储在集合中,从而删除最终的重复项。在assertEquals
中,如果Set
的大小和enum
中的值的数量相等,这意味着没有重复的ID。@Chrizzldi:基本上与我的相同,只是使用了lambda和streams(至少需要Java 8)并将其放入单元测试assertEquals
中,这里只显示有一个重复的ID,而不是确切的ID。所以这可能没有什么帮助,非常感谢你的努力。我有一个想法(见我的编辑2)来解决这个问题。现在需要休息一下,但我会回来汇报。@Ben我想向OP展示用单元测试验证这些东西是多么方便。
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());
}
}
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
}
}
}
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());
}
}
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();
}
}