3

例外がスローされたかどうかだけでなく、例外によって生成された特定のメッセージがスローされることを (JUnit を使用して) テストできるかどうかを知りたいです。たとえば、例外がスローされたため、JunitTest.java コードは実際にテストに合格しますが、例外によって生成された文字列が「テスト例外: 整数は負ではない可能性があります..」と等しいこともテストしたい場合、これは可能です?

TestException.java

public class TestException extends Exception {  
    /**
     * @param message informative message about the problem found
     */
    public TestException (String message) {
        super("Test Exception: " + message);
    }
}

テスト.java

public void function(Integer mustBePositive) throws TestException {
    if (mustBePositive < 0) {
        throw new TestException("Integer may not be negative..");
    }
    else {
        mustBePositive = myNum
    }
}

JunitTest.java

import org.junit.*;

public class JUnitTest {

    @Test(expected = TestException.class)
    public void functionTest() throws TestException {
        function(-1);
    }
}
4

7 に答える 7

8

注: @Matthew の回答の方が優れていると思います。

次の構造を使用できます。これは、正しい例外がスローされたこと ( TestException.class)、メッセージが期待どおりであることをテストします。

@Test(expected = TestException.class)
public void test_function_negative() {
    try {
        function(-5);
    } catch (TestException ex) {
        assertEquals("Integer may not be negative..", ex.getMessage());
        throw ex;
    }
}

EDIT
例外を再スローする理由 (コメントに従って): 以下の最初のテストは成功しますが、2 番目のテストは成功しません。したがって、検証のレイヤーが追加されます。以下のコードで ExceptionB をキャッチすると、両方のテストが失敗します。

@Test
public void test1() throws ExceptionB {
    try {
        throw new ExceptionA();
    } catch (ExceptionA e) {
        assertEquals("message", e.getMessage());
    }
}

@Test(expected=ExceptionB.class)
public void test2() throws ExceptionA {
    try {
        throw new ExceptionA();
    } catch (ExceptionA e) {
        assertEquals("message", e.getMessage());
        throw e;
    }
}

public class ExceptionA extends Exception{
    @Override
    public String getMessage() {
        return "message";
    }
}
public class ExceptionB extends ExceptionA{}
于 2012-04-13T12:14:00.550 に答える
6

標準の JUnit TestRule ExpectedExceptionを使用できます。これにより、例外がスローされることをテストしたり、例外に付随するメッセージをテストしたりできます。例えば:

public static class HasExpectedException {
  @Rule
  public ExpectedException thrown= ExpectedException.none();

  @Test
  public void throwsNothing() {
    // no exception expected, none thrown: passes.
  }

  @Test
  public void throwsNullPointerException() {
    thrown.expect(NullPointerException.class);
    throw new NullPointerException();
  }

  @Test
  public void throwsNullPointerExceptionWithMessage() {
    thrown.expect(NullPointerException.class);
    thrown.expectMessage("happened?");
    thrown.expectMessage(startsWith("What"));
    throw new NullPointerException("What happened?");
  }
}

は String (メッセージの部分文字列) または MatcherのexpectMessage()いずれかを取るため、正規表現のチェックなどを行うことができます。

于 2012-04-13T18:40:51.750 に答える
2
assertEquals("Test Exception: Integer may not be negative..", e.getMessage());
于 2012-04-13T12:12:14.643 に答える
1

私はこのようにします:

  @Test
  public void functionTest() throws TestException {
    try {
        function(-1);
        fail("This should have thrown an exception.");
    } catch (TextException e) {
       assertEquals("exception test produced an unexpected message", EXPECTED_TEXT, e.getMessage());
    }
  }

これはエレガントではないかもしれませんが、理解しやすく、すべての基本をカバーしています。免責事項 - 私はそれをコンパイルしていません。

于 2012-04-13T12:14:30.693 に答える
1

catch-exceptionは、このシナリオをサポートするために作成されています。

import static com.googlecode.catchexception.CatchException.*;

public void testFunction() throws Exception {
    verifyException(obj).function(-1);
    assertEquals("Integer may not be negative..", 
                 caughtException().getMessage());
}
于 2012-06-22T15:54:41.033 に答える
1

他の人は、これをテストするために使用できる構造をすでに指摘していますが、これは非常に壊れやすい可能性があるため、メッセージ自体はテストしません。

必要なすべてのデータを取得し、そのデータがそこにあることをアサートするカスタム例外を作成する必要があります。メッセージが本当に気になる場合は、例外自体で個別に単体テストできます。

あなたの例を考えると:

public void function(Integer mustBePositive) throws TestException {
    if (mustBePositive < 0) {
        throw new TestException("Integer may not be negative..");
    }
    else {
        mustBePositive = myNum
    }

NegativeNumberException をスローするだけです。数値を本当に知りたい場合は、コードを変更してそれを引数として受け取ることができます。

public void function(Integer mustBePositive) throws TestException {
    if (mustBePositive < 0) {
        throw new NegativeNumberException(mustBePositive);
    }
    else {
        mustBePositive = myNum
    }

次に、テストで:

 @Test(expected = NegativeNumberException.class)
 public void functionTest() throws TestException {
    try {
        function(-1);
    } catch (NegativeNumberException nne) {
        assertThat(nne.getNumber(), equalTo(-1));
    }
 }

例外は適切と思われる方法でメッセージを生成できるようになり、その出力への変更はテスト コードの残りの部分に波及しません。

于 2012-04-13T12:24:45.353 に答える
-1

org.junit をインポートします。* ;

公開クラス JUnitTest {

@Test
public void functionTest() throws TestException {
    try {
        function (-1);
        fail("");
    } catch (TestException e) {
        if (!e.getMessage().equals("Integer may not be negative..")) 
          fail("");
    }
}
于 2012-04-13T12:14:41.427 に答える