0

みんな私はJUnitテストに不慣れで、それをしっかりと把握しようとしています。現在、負のint値を読み取ってグラフを作成するとIllegalArgumentExceptionをスローするコンストラクター(有向グラフを作成するDigraphクラス用)のJUnitテストを作成していますすべてが問題ない場合 (ノード値の数) は 0 より大きくなります。

ダイグラフ クラス:

 In in = new In();
 public Digraph(In in) {
  try {
    this.nodes = in.readInt();
    System.out.println("Total nodes in graph: "+ nodes);
    if (nodes < 0) throw new IllegalArgumentException("Number of vertices must be > 0);
    int E = in.readInt();
    if (E < 0) throw new IllegalArgumentException("Number of edges must be >0);
  }catch (NoSuchElementException e) {
     throw new InputMismatchException("Invalid input format in Digraph constructor");
  }

以下は、私が書こうとしているテストです。

@Rule
  public ExpectedException exception = ExpectedException.none();  

@Test(expected = IllegalArgumentException.class)
public void DigraphIn() {

    Digraph G = new Digraph(in.readInt());

    exception.expect(IllegalArgumentException.class);
    exception.expectMessage("Vertices can't be nagative");
    exception.expectMessage("Invalid input format in Digraph constructor");
    exception.expectMessage("Number of edges in a Digraph must be nonnegative");
try{
}catch (AssertionError e){
    }
}

1 つ (または 2 つ) のテスト ケースを使用して両方のケースをテストするにはどうすればよいですか? "in" で -ve 値が検出されない場合は、java.lang.AssertionError を取得します。それ以外の場合はテストに合格します。前もって感謝します

4

2 に答える 2

2

多くのテストケースが必要です。例外ごとに 1 つあるとよいでしょう。

実行する各テストは異なり、異なる方法で処理する必要があります。

良いリファレンスはこれです: Junit Cookbook

実際、あなたのコードにエラーがありました。テスト ケースでは、以下のように共同作業者をモックできます。「mockito」モック ライブラリを使用して、呼び出しごとに異なる値を返すモックを作成しました。

基本的に次のようなものが必要です。

@Test(expected = IllegalArgumentException.class)
public void DigraphInThatThrowsExceptionForVertices() {
    In in = Mockito.mock(In.class);
    when(in.readInt()).thenReturn(-1);
    Digraph G = new Digraph(in);
    fail();
}

@Test(expected = IllegalArgumentException.class)
public void DigraphInThatThrowsExceptionForEdges() {
    In in = Mockito.mock(In.class);
    when(in.readInt()).thenReturn(10).thenReturn(-1);
    Digraph G = new Digraph(in);
    fail();
}

@Test
public void DigraphInThatDoesNotThrowException() {
    In in = Mockito.mock(In.class);
    when(in.readInt()).thenReturn(10).thenReturn(15);
    Digraph G = new Digraph(in.readInt());
}

このようにして、テスト コードはよりクリーンで読みやすくなります。

于 2013-09-23T20:17:02.627 に答える
1

メソッドをテストするときは、実際にメソッドを呼び出して実行します。例外はメソッドの残りの処理をキャンセルするため、テストはテストごとに 1 つの例外のみを検証できます。したがって、例外がスローされる可能性のある場所ごとに 1 つのテストが必要です。

単体テストで例外がスローされることを確認する場合、基本的に 3 つの方法があります。

try-catch ブロック:

@Test
public void myTest() {
    try {
        myClass.myMethod(42);
        fail();
    } catch(final IllegalArgumentException e) {
        assertEquals("something went wrong", e.getMessage());
    }
}

-expected注釈の@Test- 属性:

@Test(expected=IllegalArgumentException.class)
public void myTest() {
    myClass.myMethod(42);
}

ExpectedException:

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Test
public void myTest() {
    expectedException.expect(IllegalArgument.class);
    expectedException.expectMessage("something went wrong");

    myClass.myMethod(42);
}

あなたの例では、3つすべてを使用しようとしています。

例外のテスト方法を比較すると、スローされた例外を実際に検証できるのは 1 番目と 3 番目の方法だけであり、同じタイプの例外が複数の場所からスローされる可能性のある方法をテストするのに適しています。例外メッセージを使用して、例外が発生した場所から例外がスローされたことを確認します。

2 番目のものは、はるかに読みやすいですが、テスト対象のメソッドによってスローされる例外を区別することはできません。ほとんどの場合、他の 2 つほどの価値はありません。

1 番目と 3 番目のうち、3 番目が断然読みやすく、個人的にもお気に入りです。

テスト対象のメソッドは、実行ごとに 1 つの例外しかスローできないため、例外がスローされる可能性のある場所ごとに 1 つのテスト メソッドが必要です。

public class DiagraphTest {

    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    private Diagraph diagraph;
    private In in;

    @Before
    public void setup() {
        in = mock(In.class); 
    }

    @Test
    public void constructorShouldThrowExceptionWhenNumberOfVerticesIsLessThanOne() {
         expectedException.expect(IllegalArgumentException.class);
         expectedException.expectMessage("vertices must be > 0"); //expectMessage only needs a substring of the exception-message

         doReturn(-1).when(in).readInt();

         new Diagraph(in);
    }

    @Test
    public void constructorShouldThrowExceptionWhenNumberOfEdgesIsLessThanOne() {
         expectedException.expect(IllegalArgumentException.class);
         expectedException.expectMessage("edges must be > 0"); 

         when(in.readInt()).thenReturn(42, -1);

         new Diagraph(in);
    }

    //as to the last exception, I really can't see that it will ever be thrown in that try-block, but here's a test for that as well..
    @Test
    public void constructorShouldThrowInputMismatchExceptionIfReceivedNoSuchElementException() {
         expectedException.expect(InputMismatchException.class);
         expectedException.expectMessage("Invalid input format); 

         doThrow(new NoSuchElementException("phail")).when(in).readInt();

         new Diagraph(in);
    }

}

于 2013-09-23T21:20:21.873 に答える