特定のメッセージの例外がgoogle-truthを使用してスローされているかどうかをテストしたいだけです。
@Test(expected=
を使用してjunitを使用してそれを行うのは非常に簡単ですが、真実でそれを行う方法を理解することはできません。 ThrowableSubject の周りにサンプルはありません。
この種のテストでは、プレーンなJUnit
を使用する必要がありますか?
[更新しました]
Truthの作成者は、JUnit 4.13/5のassertThrows()
メカニズムを使用することをお勧めします。これは、Truthでのサポートを実際に必要としないためです。これは次のようになります。
_SpecificException e =
assertThrows(SpecificException.class, () -> doSomethingThatThrows());
assertThat(e).hasMessageThat().contains("blah blah blah");
assertThat(e).hasCauseThat().isInstanceOf(IllegalStateException.class);
assertThat(e).hasCauseThat().hasMessageThat().contains("blah");
_
これは、try/fail/catchよりも簡潔であり、「失敗の欠落」の問題を回避し、TruthのThrowableSubject
を使用してアサートできるオブジェクトを返すため、推奨されます。
assertThrows()
がない場合は、try/fail/catchパターンを使用してください。これは明確で、明示的です。
_try {
doSomethingThatThrows();
fail("method should throw");
} catch (SpecificException e) {
// ensure that e was thrown from the right code-path
// especially important if it's something as frequent
// as an IllegalArgumentException, etc.
assertThat(e).hasMessage("blah blah blah");
}
_
_@Rule ExpectedException
_と@Test(exception=...)
はJUnitに存在しますが、合格するが失敗するはずのテストを書くことができる微妙な(そして微妙ではない)方法がある限り、これらは真理チームによって推奨されません。 。
これはtry/fail/catchにも当てはまりますが、内部的にGoogleは error-prone を使用してこれを軽減します。これは、このパターンが失敗を省略しないことを確認する静的コンパイル時チェックを提供します。 ()など。エラーが発生しやすい、または他の静的分析チェックを使用してこれらをキャッチすることを強くお勧めします。残念ながら、ルールベースおよびアノテーションベースのメソッドは、このtry/catchブロックほど静的分析に適していません。
ここでの更新として、Christianが説明したパターンから離れ、 Issue#219 は閉じられ、JUnitの expectThrows()
(coming 4.1 では、同様のメソッドが TestNGのAssert
)にすでに存在します。
expectThrows()
と連携して、Truthを使用して スローされた例外に関するアサーション を作成できます。したがって、クリスチャンの例は次のようになります。
SpecificException expected = expectThrows(
SpecificException.class, () -> doSomethingThatThrows());
assertThat(expected).hasMessageThat().contains("blah blah blah");
現在、予想されるException
をgoogle-truth
で検証する組み込みの方法はありません。次のいずれかを実行できます。
expected=
を使用しますtry...catch
で囲むことにより、テストを「醜い」方法で記述します これはユニットテストでguava
が行うことですgoogle-truth
には、同様の機能はないと思います。 Java 1.6 をサポートしているからです。
import com.google.common.truth.FailureStrategy;
import com.google.common.truth.Subject;
import com.google.common.truth.SubjectFactory;
import org.junit.Test;
import Java.util.concurrent.Callable;
import static com.google.common.truth.Truth.assertAbout;
public class MathTest {
@Test
public void addExact_throws_ArithmeticException_upon_overflow() {
assertAbout(callable("addExact"))
.that(() -> Math.addExact(Integer.MAX_VALUE, 1))
.willThrow(ArithmeticException.class);
}
static <T> SubjectFactory<CallableSubject<T>, Callable<T>> callable(String displaySubject) {
return new SubjectFactory<CallableSubject<T>, Callable<T>>() {
@Override public CallableSubject<T> getSubject(FailureStrategy fs, Callable<T> that) {
return new CallableSubject<>(fs, that, displaySubject);
}
};
}
static class CallableSubject<T> extends Subject<CallableSubject<T>, Callable<T>> {
private final String displaySubject;
CallableSubject(FailureStrategy failureStrategy, Callable<T> callable, String displaySubject) {
super(failureStrategy, callable);
this.displaySubject = displaySubject;
}
@Override protected String getDisplaySubject() {
return displaySubject;
}
void willThrow(Class<?> clazz) {
try {
getSubject().call();
fail("throws a", clazz.getName());
} catch (Exception e) {
if (!clazz.isInstance(e)) {
failWithBadResults("throws a", clazz.getName(), "throws a", e.getClass().getName());
}
}
}
}
}