Search code examples
javajunitgoogle-truth

How to test that an expected exception is being thrown using google-truth?


I just want to test if an exception with a given message is being thrown using google-truth.

Is quite easy to do that using junit using @Test(expected=, but I'm unable to figure out how to do that with truth. There are no samples around ThrowableSubject.

Should I stick with plain JUnit for these kind of tests?


Solution

  • [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.