javaunit-testing

General Information about how to check for non unique IDs in Java code


In a very huge project, there are a lot of ExceptionClasses where exception details are implemented as enum.

NAME_OF_EXCEPTION_DETAIL(ID, PRIORITY)

e.g.:

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

In some cases the exception details ID is the same, which should never have happened. It is pretty damn possible that there are more duplicates but this project is to huge to check this by hand ...

Is there a smart way to check the code for duplicates, e.g. UnitTesting - never used it before.

Thanks for your help!

Edit (Bens answer is a good way to solve this problem when using just one enum): To be more clear in my specific task this are the circumstances. There are a lot of Classes that are written to handle ExceptionDetails e.g.

TopicOneExceptionDetails.java
TopicTwoExceptionDetails.java  (and so on)

Each of these classes defines an enum for this topic like so:

public enum TopicOneExceptionDetails implements ApplicationException.ExceptionDetails { .... }

followed by the declaration of errors related to TopicOne errors e.g.

SETTING_TIMEZONE_FAILED(55, ...)
Setting_DATETIME_FAILED(56, ...)

in this enum for TopicOne every error ID has to be unique. But for example ID 55 (here used for SETTING_TIMEZONE_FAILED) can be used in the declaration of errors related to TopicTwo without a problem.

Edit 2 (Use reflections ?) I found a pretty informative answer about java Reflections written by Matt Sheppard. I think this could solve my problem. I need to take a break but I will report back. My current thoughts are:

Reflections reflections = new Reflections("project.de")
for(Class<? extends ApplicationException.ExceptionDetails> exceptionDetailsClasses : reflections.getSubTypesOf(ApplicationException.ExceptionDetails.class)){
for ( ... ) .. }

I should be able to check for the IDs e.g. like Ben advised. I'll report back later.

EDIT 3 (Question Solved!) Like in edit 2 described I was able to easily solve this issue using 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());
      }
    }
  }
}

Special thanks to Ben and Spotted for their effort. The both answered with some pretty good examples in how to resolve the topics question in general. In my case it just got a bit more complicated.


Solution

  • One way to check your Enum for duplicate IDs (It's not tested, but should work).
    You can use parts of this code for your unit-test (or use it standalone):

    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
          }
       }
    }
    

    Cheers!