web-dev-qa-db-ja.com

JUnitテスト-予想される例外を分析する

JUnitでは、現在、テストで例外を予期するために注釈を使用しています。

この例外を分析する方法はありますか?たとえば、CriticalServerExceptionが必要ですが、getMessageメソッドの内容を確認する必要もあります。

41
Farid

JUnit 4.7以上の場合 ExpectedException

this question に例があります。以下にコピーします:

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

@Test
public void testRodneCisloRok(){
    exception.expect(IllegalArgumentException.class);
    exception.expectMessage("error1");
    new RodneCislo("891415",dopocitej("891415"));
}
68
Filippo Vitale

あなたがすべきかどうかはわかりません。 try-catchブロックを使用してエラーメッセージを確認するのはjunit3ishです。 @Test(expected=CriticalServerException.class)を記述でき、エラーメッセージをチェックするためだけに「戻る」ことを試みて、期待される例外をフェッチするためにtry-catchを再度使用することができるようになりました。

IMOでは、@Test(expected=CriticalServerException.class)注釈をそのままにして、エラーメッセージを無視する必要があります。エラーメッセージを確認することは、技術的な価値ではなく、より「人間が読める」文字列であるため、大幅に変更することもできますが、注意が必要です。例外に特定のエラーメッセージを強制しますが、例外の生成者と選択したエラーメッセージがわからない場合があります。

一般に、メソッドが例外をスローするかどうかをテストし、実際のエラーメッセージがどのように見えるかではありません。エラーメッセージが非常に重要な場合は、スローされる例外のサブクラスの使用を検討し、@Test(expected=...)でチェックすることをお勧めします。

21
Progman
try{ 
    //your code expecting to throw an exception
    fail("Failed to assert :No exception thrown");
} catch(CriticalServerException ex){
    assertNotNull("Failed to assert", ex.getMessage()) 
    assertEquals("Failed to assert", "Expected Message", ex.getMessage());
}
12
Jigar Joshi
try
{
    // your code

    fail("Didn't throw expected exception");
}
catch(CriticalServerException e)
{
    assertEquals("Expected message", e.getMessage());
}
2
Brian
try {
    // test code invacation
    fail("Exception not throw!!!");
} catch(CriticalServerException ex) {
    assertTrue("Invalid exception data", ex.toString().contains("error text"));
}
2
Alex

テストするテストケースが多数ある場合は、MethodRuleを一般的なソリューションとして使用します

public class ExceptionRule implements MethodRule {
    @Override
    public Statement apply(final Statement base, final FrameworkMethod method, Object target) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                try {
                    base.evaluate();
                    Assert.fail();
                } catch (CriticalServerException e) {
                    //Analyze the exception here
                }
            }
        };    
    }
}

次に、テストクラスに対してルールを使用します。

@Rule public ExceptionRule rule = new ExceptionRule(); 

アノテーションを使用してそれを行う方法はないと思います。 catchブロックでメッセージを確認できるtry-catch方法にフォールバックする必要がある場合があります

1
Ankit Bansal

catch-exception を使用します。

catchException(obj).doSomethingCritical();
assertTrue(caughtException() instanceof CriticalServerException);
assertEquals("Expected Message", caughtException().getMessage());
0
rwitzel

fluent-exception-rule を見て、「Junit ExpectedExceptionルールとAssertJのアサーションの利便性を組み合わせています。」

import pl.wkr.fluentrule.api.FluentExpectedException;
...
@Rule
public FluentExpectedException thrown = FluentExpectedException.none();

@Test
public void testDoSomethingCritical() {
    thrown.expect(CriticalServerException.class).hasMessage("Expected Message").hasNoCause();
    obj.doSomethingCritical();
}
0
Marcin

Java 8ソリューション

私が書いたユーティリティ関数は次のとおりです。

public final <T extends Throwable> T expectException( Class<T> exceptionClass, Runnable runnable )
{
    try
    {
        runnable.run();
    }
    catch( Throwable throwable )
    {
        if( throwable instanceof AssertionError && throwable.getCause() != null )
            throwable = throwable.getCause(); //allows "assert x != null : new IllegalArgumentException();"
        assert exceptionClass.isInstance( throwable ) : throwable; //exception of the wrong kind was thrown.
        assert throwable.getClass() == exceptionClass : throwable; //exception thrown was a subclass, but not the exact class, expected.
        @SuppressWarnings( "unchecked" )
        T result = (T)throwable;
        return result;
    }
    assert false; //expected exception was not thrown.
    return null; //to keep the compiler happy.
}

私のブログから引用

次のように使用します。

@Test
public void testThrows()
{
    RuntimeException e = expectException( RuntimeException.class, () -> 
        {
            throw new RuntimeException( "fail!" );
        } );
    assert e.getMessage().equals( "fail!" );
}

また、の理由を読みたい場合は、notのメッセージを確認する必要がありますあなたの例外は、これを参照してください: https://softwareengineering.stackexchange.com/a/278958/41811

0
Mike Nakis

メッセージと例外タイプを比較したい場合は、以下のコードスニペットを試してください。

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

    expectedException.expect(IllegalArgumentException.class);
    expectedException.expectMessage("Parameter is not valid"); //check string contains
    expectedException.expectMessage(CoreMatchers.equalTo("Parameter is not valid")); //check string equals

注:これは、junit 4.9以降で機能します。

0
Meet