I have a project where I have tests where I deliberately cause a problem and then verify the code responds the way I want it. For this I want to be sure the exceptions not only are the right class but they must also carry the right message.
So in one of my existing (junit 4) tests I have something similar to this:
public class MyTests {
@Rule
public final ExpectedException expectedEx = ExpectedException.none();
@Test
public void testLoadingResourcesTheBadWay(){
expectedEx.expect(MyCustomException.class);
expectedEx.expectMessage(allOf(startsWith("Unable to load "), endsWith(" resources.")));
doStuffThatShouldFail();
}
}
I'm currently looking into fully migrating to junit 5 which no longer supports the @Rule and now has the assertThrows that seems to replace this.
What I have not been able to figure out how to write a test that not only checks the exception(class) that is thrown but also the message attached to that exception.
What is the proper way to write such a test in Junit 5?
In JUnit 5, to write the test code that is expected to throw an exception, we should use Assertions. assertThrows(). In the given test, the test code is expected to throw an exception of type ApplicationException or its subtype. Note that in JUnit 4, we needed to use @Test(expected = NullPointerException.
When using JUnit 4, we can simply use the expected attribute of the @Test annotation to declare that we expect an exception to be thrown anywhere in the annotated test method. In this example, we've declared that we're expecting our test code to result in a NullPointerException.
Create a java class file named TestRunner. java in C:\>JUNIT_WORKSPACE to execute test case(s). Compile the MessageUtil, Test case and Test Runner classes using javac. Now run the Test Runner, which will run the test cases defined in the provided Test Case class.
JUnit 4 Assert Exception Message If we want to test exception message, then we will have to use ExpectedException rule.
Since Assertions.assertThrows
returns instance of your exception you can invoke getMessage
on the returned instance and make assertions on this message :
Executable executable = () -> sut.method(); //prepare Executable with invocation of the method on your system under test
Exception exception = Assertions.assertThrows(MyCustomException.class, executable); // you can even assign it to MyCustomException type variable
assertEquals(exception.getMessage(), "exception message"); //make assertions here
Thanks to @michalk and one of my colleagues this works:
Exception expectedEx = assertThrows(MyCustomException.class, () ->
doStuffThatShouldFail()
);
assertTrue(expectedEx.getMessage().startsWith("Unable to load "));
assertTrue(expectedEx.getMessage().endsWith(" resources."));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With