2009-07-03 17 views
13

私は現在、小さなライブラリの単体テストのセットを完成させようとしています。異なる実装が存在するようにしたいので、このテストセットを(a)汎用的にして、別の実装をテストするために再利用できるようにし、可能な限り完全なものにします。 (b)の部分については、enum型をテストするためのベストプラクティスがあるかどうかを知りたいと思います。だから、例えば次のように私は列挙型を持っている:列挙型をテストするには?

public enum Month { 
    January, 
    February, 
    ... 
    December; 
} 

ここで私は、すべてのenum型が実際に存在することを確認します。それは必要なのでしょうか?現在、私は次の例のようにHamcrestsにassertThatを使用しています:

assertThat(Month.January, is(notNullValue())); 

不足している「1月」列挙型は1つが作成欠けている列挙型で修正することができ、コンパイル時エラーになります。

編集..私はここにJavaを使用していますが、あなたの答えは異なる言語のためであれば、私は気にしない

:mkatoとマーク・ヒースとして

は、両方のテストの列挙型を指摘している可能性があなたがそこにない列挙型を使用しているときにコンパイラはコンパイルされないので、必要ではありません。しかし、私はまだ別の実装で同じテストを実行する別々のTCKのようなtest.jarを構築したいので、これらの列挙型をテストしたいと思います。だから、私の質問は、より多くのように意味されていた:列挙型をテストする最良の方法は何ですか?

もう少しそれについて考えて後、私はに上Hamcrestステートメントを変更:1月がない場合、この文は今(まだ)NPEをスロー

assertThat(Month.valueOf("January"), is(notNullValue())); 

。このアプローチに何か問題はありますか?

答えて

17

列挙型の場合、実際にメソッドがある場合にのみテストします。それがあなたの例のような純粋な価値のある列挙型ならば、私は気にしないと言っています。

しかし、あなたはそれをテストしたいので、2番目のオプションを使うことは、最初のものよりもはるかに優れています。最初の問題は、IDEを使用する場合、列挙型の名前を変更すると、テストクラス内の名前の名前も変更されるということです。

+0

私は、テストしたい1つのメソッドを持つ列挙型を持っています。私は単体テストのルーキーであり、そのメソッドのテストケースを記述する方法を見つけることができません。 。 – dirtydexter

+0

"assertThat(Month.January、is(notNullValue()));" OPの質問ではあなたのための例が十分ではない、私はあなたが別の質問としてそれを聞いて、あなたがテストしようとしているものの例を提供する方が良いと思う。 JUnit自体の助けが必要なように私に聞こえます。 – aberrant80

+0

そうですね、ありがとうございます。 – dirtydexter

3

コードで月をすべて使用すると、IDEでコンパイルできなくなるため、単体テストは必要ありません。

ただし、リフレクションで使用している場合は、1か月を削除してもコンパイルされるため、ユニットテストを行うことは有効です。

+0

単体テストでは、あなたの月がどのように使用されるのか、それらの将来の使用方法についての知識はありません。これは、すべての月が存在しない場合にアプリケーションが現在コンパイルされていなくても、単体テストを含める必要があることを意味します。警告:単純なオブジェクト(メソッドを持たないenumなど)を気にする前に、複雑なオブジェクトが単体テストによって適切にカバーされていることを確認してください。 –

4

通常、私はそれは残酷だと言いますが、時々列挙型の単体テストを書く理由があります。

列挙メンバに割り当てられた値を決して変更しないでください。また、以前の永続化データの読み込みが失敗することがあります。同様に、明らかに未使用のメンバーは削除してはいけません。ユニットテストは、開発者がその影響を認識することなく変更を行うのを防ぐために使用できます。

8

私はaberrant80に同意します。

列挙型の場合、実際にメソッドがある場合にのみテストします。 あなたの例のような純粋な価値のある列挙型の場合は、 気にしないといいでしょう。

しかし、あなたがそれをテストすることに熱心であるので、2番目のオプションは、最初のものよりもはるかに良い です。最初の問題は、 IDEを使用している場合、enumの名前を変更すると、 の名前がテストクラスに変更されるということです。

このユニットのテストを追加することで、Enumが非常に便利になります。大規模なコードベースで作業する場合、ビルド時間が短くなり、単体テストは機能を検証するためのより速い方法になります(テストでは依存関係のみが構築されます)。もう一つの大きな利点は、他の開発者があなたのコードの機能を意図せずに変更できないことです(非常に大きなチームでは大きな問題です)。

すべてのテスト駆動開発では、Enumsメソッドを使用したテストでは、コードベースのバグの数を減らすことができます。

簡単な例

public enum Multiplier { 
    DOUBLE(2.0), 
    TRIPLE(3.0); 

    private final double multiplier; 

    Multiplier(double multiplier) { 
     this.multiplier = multiplier; 
    } 

    Double applyMultiplier(Double value) { 
     return multiplier * value; 
    } 

} 

public class MultiplierTest { 

    @Test 
    public void should() { 
     assertThat(Multiplier.DOUBLE.applyMultiplier(1.0), is(2.0)); 
     assertThat(Multiplier.TRIPLE.applyMultiplier(1.0), is(3.0)); 
    } 
} 
+0

私は、テストしたい1つのメソッドを持つ列挙型を持っています。私は単体テストのルーキーであり、そのメソッドのテストケースを記述する方法を見つけることができません。 。 – dirtydexter

+0

@dirtydexter例を使って更新された解答を見てください。 –

2

例により、正確にいくつかの値を持っている場合は、テストすることができます。

for(MyBoolean b : MyBoolean.values()) { 
    switch(b) { 
    case TRUE: 
     break; 
    case FALSE: 
     break; 
    default: 
     throw new IllegalArgumentException(b.toString()); 
} 

for(String s : new String[]{"TRUE", "FALSE" }) { 
    MyBoolean.valueOf(s); 
} 

を誰かが削除するか、値を追加した場合、テストの一部が失敗します。