有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

单元测试关于如何在Java代码中检查非唯一ID的一般信息

在一个非常庞大的项目中,有许多异常类,其中异常详细信息以enum的形式实现

NAME_OF_EXCEPTION_DETAIL(ID, PRIORITY)

例如:

NO_LICENSE_FOUND(100, 0)
UNSUPPORTED_LICENSE(101, 1)
WRONG_LICENSE_FOR_VERSION(101, 0)

在某些情况下,异常详细信息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(使用反射?) 我发现了一个由Matt Sheppard编写的关于java Reflectionspretty informative answer。我想这可以解决我的问题。我需要休息一下,但我会回来报告的。我目前的想法是:

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的努力。两人都用一些很好的例子回答了如何解决一般的主题问题。就我而言,它只是变得更复杂了一点


共 (2) 个答案

  1. # 1 楼答案

    当然,单元测试是检测(有把握地)此类问题的一种很好的方法

    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();
        }
    }
    
  2. # 2 楼答案

    单向检查枚举是否存在重复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
          }
       }
    }
    

    干杯