22

私は現在、小さなライブラリ用の単体テストの多かれ少なかれ完全なセットを構築しようとしています。さまざまな実装が存在できるようにしたいので、この一連のテストを (a) さまざまな実装をテストするために再利用できるように一般的なものにし、(b) できるだけ完全なものにしたいと考えています。(b) の部分については、列挙型をテストするためのベスト プラクティスがあるかどうかを知りたいです。たとえば、次のような列挙型があります。

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

ここで、すべての列挙型が実際に存在することを確認したいと思います。それも必要ですか?assertThat現在、次の例のようにHamcrests を使用しています。

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

「January」列挙型が欠落しているとコンパイル時エラーが発生しますが、欠落している列挙型を作成することで修正できます。

ここではJavaを使用していますが、あなたの答えが別の言語に対するものであってもかまいません..

編集:

mkato と Mark Heath の両方が指摘しているように、存在しない列挙型を使用している場合、コンパイラはコンパイルされないため、列挙型のテストは必要ない可能性があります。しかし、異なる実装で同じテストを実行する別の TCK のような test.jar を構築したいので、これらの列挙型をテストしたいと思います。したがって、私の質問は次のようなものでした:列挙型をテストする最良の方法は何ですか?

もう少し考えた後、上記の Hamcrest ステートメントを次のように変更しました。

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

このステートメントは、1 月が (まだ) ない場合に NPE をスローするようになりました。このアプローチに問題はありますか?

4

5 に答える 5

32

列挙型については、実際にメソッドが含まれている場合にのみテストします。あなたの例のような純粋な値のみの列挙型の場合は、気にしないでください。

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

于 2009-07-09T13:09:42.957 に答える
14

aberrant80に同意します。

列挙型については、実際にメソッドが含まれている場合にのみテストします。あなたの例のような純粋な値のみの列挙型の場合は、気にしないでください。

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

列挙型の単体テストが非常に役立つ可能性があることを追加して、それを拡張します。大規模なコード ベースで作業している場合、ビルド時間が長くなり始め、単体テストは機能を検証するためのより迅速な方法になる可能性があります (テストは依存関係をビルドするだけです)。もう 1 つの非常に大きな利点は、他の開発者が意図せずにコードの機能を変更できないことです (非常に大規模なチームでは大きな問題になります)。

また、すべてのテスト駆動開発では、列挙型メソッドに関するテストにより、コード ベースのバグの数が減少します。

簡単な例

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));
    }
}
于 2011-10-24T21:39:32.180 に答える
5

例として、正確にいくつかの値があるかどうかをテストできます。

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

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

于 2013-10-02T03:09:18.487 に答える
5

通常はやり過ぎだと思いますが、列挙型の単体テストを作成する理由が時折あります。

列挙メンバーに割り当てられた値を決して変更してはならない場合があります。そうしないと、従来の永続データの読み込みが失敗します。同様に、明らかに使用されていないメンバーは削除してはなりません。単体テストを使用して、開発者が影響を認識せずに変更を加えないようにすることができます。

于 2009-07-03T15:01:27.413 に答える
4

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

しかし、リフレクションで使っている場合は、1ヶ月削除してもコンパイルされるので、単体テストを入れるのは有効です。

于 2009-07-03T14:55:58.067 に答える