2016-10-13 5 views
0

非常に巨大なプロジェクトでは、例外の詳細がenumとして実装されているExceptionClassesがたくさんあります。一般Javaコードで一意でないIDを確認する方法

NAME_OF_EXCEPTION_DETAIL(ID, PRIORITY) 

例えば:

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

いくつかのケースでは、例外の詳細IDが同じで、ウィッヒが起こったことがないはずです。可能であれば重複している可能性がありますが、このプロジェクトは手作業でこれをチェックするために膨大なものになります...

重複のコードをチェックするスマートな方法はありますか? UnitTesting - それを使用したことはありません。

ありがとうございました!

編集(ベンズの答えは一つだけ列挙型を使用する場合にこの問題を解決するための良い方法です): これは状況です私の特定のタスクに、より明確にします。 ExceptionDetailsを処理するために作成されたクラスがたくさんあります。

TopicOneExceptionDetails.java 
TopicTwoExceptionDetails.java (and so on) 

これらのクラスのそれぞれのでように、このトピックの列挙をdefindes:

例えばTopicOneエラーに関連するエラーの宣言が続く
public enum TopicOneExceptionDetails implements ApplicationException.ExceptionDetails { .... } 

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

この列挙体のTopicOneでは、すべてのエラーIDは一意でなければなりません。しかし、たとえばID 55(ここではSETTING_TIMEZONE_FAILEDに使用されています)は、TopicTwoに関連するエラーの宣言に問題なく使用できます。

編集2(反射を使用しますか?) 私はMatt Sheppardによって書かれたJava Reflectionsについてpretty informative answerを見つけました。私はこれが私の問題を解決できると思います。私は休憩を取る必要がありますが、私は戻って報告します。私の現在の考えは次のとおりです:

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

私はIDを確認することができます。ベンがアドバイスしたように。私は後でまた報告します。 EDIT 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()); 
    } 
} 

}}

感謝し、彼らの努力のために見つけました。両方とも、トピックの問題を一般的に解決するには、かなり良い例がいくつかありました。私の場合はちょっと複雑になりました。

+1

静的テーブル。 – Henry

+0

おもしろい、ありがとう。どのように見えるのでしょうか? – Chrizzldi

+0

exptionclassesには例外があります。静的なテーブルと比較すると、複数の静的テーブルが生成されますか?私はこれについて考えるなら、私はすべてのexpectiondetailsコールでこのチェックを実装する必要があると確信しています - そうですか? – Chrizzldi

答えて

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

乾杯を!

+0

こんにちはベン、お返事いただきありがとうございます。私はその点を見て、アイデアが好きです。事実、exeptiondetailクラスがたくさんあるので、それらをすべて見つけるのは膨大な作業になるでしょう。別の問題は、exeptiondetailsクラスが同じidを持つ別のクラスと異なる場合、同じIDを持つことが許可されていることです。私が今までに理解したことは、すべての例外の詳細クラスは抽象クラスのアプリケーションの例外を継承しています。知りません。 – Chrizzldi

+0

質問にいくつかのサンプルコードを追加しますか?私はそれがどのように実装されているか想像することはできません。列挙型は他の列挙型から継承できません。 – Ben

+0

今すぐやって! – Chrizzldi

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(); 
    } 
} 
+0

ありがとうございました。ユニットテストが私をここにさらに導くことができることを知ってよかったです。しかし、私はあなたの例を理解しているかどうかはわかりません。もし私がこれを好きなら、私の列挙はどこにあるの? – Chrizzldi

+0

@Chrizzldi最初の行はすべてのIDを 'Error'から取り出して' Set'に格納し、最終的な重複を取り除きます。 'assertEquals'において' Set'のサイズと 'enum'の値の数が等しい場合、それは重複するIDがないことを意味します。 – Spotted

+0

@Chrizzldi:基本的には** lambdas **と** streams **(最低でもJava 8 **が必要です)を使ってユニットテスト 'assertEquals'を実行するだけで、 IDが正確ではなく、重複があります。それは本当に助けにならないかもしれません。 – Ben

関連する問題