0

私は比較的単純なクラスのいくつかの単体テストを書いています:

public class Asylum {
    List<Guard> guards = new ArrayList<Guard>();
    List<Inmate> inmates = new ArrayList<Inmate>();

    public void addGuard(Guard g) { //... }
    public void addInmate(Inmate i) { //... }
}

これら2つの関数の単体テストでは、null値を渡した場合に何が起こるかを判断します。

@Test
public void addGuardNullValue() {
    asylum.addGuard(null);
    assertEquals(0, asylum.getNumGuards());
}

@Test
public void addInmateNullValue() {
    asylum.addInmate(null);
    assertEquals(0, asylum.getNumInmates());
}

私は実際にこれらの警備員、囚人、監視員などのコンテナをいくつか(> 3)持っていますが、基本的にすべてのクラスで同じ単体テストを作成することはしたくありません。

これを1つのユニットテストにまとめて、 n個のクラスをカバーする方法はありますか?

(GuardとInmateの包括的な親クラスを作成できず、両方が実装できるインターフェイスを作成できないことに注意してください。)

4

2 に答える 2

3

解決策は 2 つしかありませんが、どちらもお勧めしません。

1 つ目は、リフレクションを使用することです。クラス内のすべてのメソッドを一覧表示し、add*またはのような名前のメソッドを選択しますgetNum*。次にadd*、null 値を持つものを呼び出して、の戻り値を確認できますgetNum*。問題は、メソッド名 ( ) に偽陽性が含まれる可能性がaddGroupあり、結果のテストが読み取り (および書き込み) が困難になることです。

2番目の解決策は、に応じてaddPerson(PersonType type, Object person)ダウンキャストする方法です。静的な型チェックが削除され、不要な複雑さが追加され、さらに悪用される傾向があるため、これはひどいオプションだと思います。便利なバリエーションが見つかるかもしれないので、言及します。personPersonType

私の最終的な答えは、「やらないでください。やる価値はありません」です。より多くの行が必要になりますが、読み書きが非常に簡単で、おそらく最初の試行でバグがなくなるでしょう。

私が適切だと思う引用で締めくくりたいと思います:

デバッグは、最初にコードを書くよりも 2 倍大変です。したがって、コードをできるだけ賢く書いたとしても、定義上、それをデバッグするほど賢くはありません。(ブライアン・カーニハン)

于 2013-01-21T21:02:38.663 に答える
1

初め。正解のIMOはBoppreHのものです。しないでください。

ただし、Reflectionを使用してこれを行う方法は次のとおりです。TheReflectionAPI
のドキュメントを読み始めた方がよいでしょう。

package sandbox;
......
......
@Test
public void testAddClasses() throws Exception {
    String classesToTest[] = new String[]{"Inmate", "Guard"};
    for (String classToTest : classesToTest){
        String fullClassName = "sandbox." + classToTest;
        String addMethodName = "add" + classToTest;
        String countMethodName = "getNum" + classToTest + "s"; 

        Asylum asylum = new Asylum();

        Class asylumClass = asylum.getClass();
        Class testClass = Class.forName(fullClassName, true, asylumClass.getClassLoader());

        Method addMethod = asylumClass.getDeclaredMethod(addMethodName, testClass);
        Object voidObj = addMethod.invoke(asylum, (Object)null);

        Method countMethod = asylumClass.getDeclaredMethod(countMethodName, null);
        int count = (int) countMethod.invoke(asylum, null);

        assertEquals(0, count);
    }
}
于 2013-01-21T23:17:52.083 に答える