[updated]
The Truth authors recommend using JUnit 4.13/5's assertThrows()
mechanism, since this doesn't really need support in Truth. This would look more like:
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");
This is recommended over try/fail/catch as it is terser, avoids the "missing fail" problem, and returns an object that can be asserted-on using the ThrowableSubject
in Truth.
If you do not have assertThrows()
, then please use the try/fail/catch pattern, as this is clear and explicit.
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");
}
While @Rule ExpectedException
and @Test(exception=...)
exist in JUnit, these aren't recommended by the Truth team, insofar as they have some subtle (and less subtle) ways you can write tests that pass but which should fail.
While this is also true of try/fail/catch, internally Google mitigates this with the use of error-prone, which provides a static compile-time check to ensure that this pattern doesn't omit the fail(), etc. It is highly recommended that you use error-prone or another static analysis check to catch these. Sadly, the rule-based and annotation-based methods aren't as easily amenable to static analysis as this try/catch block.
fail()
in? – Disassemble