Jakub is a Java EE developer since 2005 and occasionally a project manager, working currently with Iterate AS. He's highly interested in developer productivity (and tools like Maven and AOP/AspectJ), web frameworks, Java portals, testing and performance and works a lot with IBM technologies. A native to Czech Republic, he lives now in Oslo, Norway. Jakub is a DZone MVB and is not an employee of DZone and has posted 155 posts at DZone. You can read more from them at their website. View Full User Profile

JUnit Tip: Verifying that an Exception with a Particular Message was Thrown

  • submit to reddit

JUnit has a hidden treasure which makes it easy to do something we have long longed for – namely not only to verify that an exception of a particular type has been thrown but also that its message contains the expected message. The hidden pearl is the @Rule ExpectedException and its JavaDoc documents well how to use it (slightly modified):

import org.junit.*;
import org.junit.rules.ExpectedException;

public static class HasExpectedException {
        public ExpectedException thrown= ExpectedException.none();

        public void throwsNothing() {
            // no exception expected, none thrown: passes.

        public void throwsNullPointerExceptionWithMessage() {
                thrown.expectMessage("What happened here?");
                thrown.expectMessage(allOf(containsString("What"), containsString("here")));
                throw new NullPointerException("What happened here?");

(As you might have noticed, it uses Hamcrest matchers; containsString isn’t included directly in junit and thus you’d need junit-dep + hamcrest jars.)

From http://theholyjava.wordpress.com/2011/09/16/junit-tip-verifying-that-an-exception-with-a-particular-message-was-thrown/

Published at DZone with permission of Jakub Holý, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)


Manuel Jordan replied on Fri, 2011/09/23 - 8:19am

Thank you for share this

Loren Kratzke replied on Sat, 2011/09/24 - 6:32pm

This is totally wrong. Do not test the contents of a message, perhaps the presence, but not the contents. Just because you can test it does not mean that you should test it. If I want to expand on that message, oh, test breaks. That's right, because you are forcing developers to write code twice - once in the code and copy/paste in the test. I am sorry to be negative, but I rip that kind of crap out when I see it and then send a scolding message to the developer who did it to never do that again.

Test function, NOT implementation. The contents of a message (should it change) is best handled via code review if at all, but not via unit test.

Repeat: Test function, NOT implementation.

Tomek Kaczanowski replied on Mon, 2011/09/26 - 6:50am

@Loren, I think you missed the point. If your code throws two exceptions of the same type (e.g. when validating parameters: IllegalArgumentException("id can not be null") and IllegalArgumentException("amount can not be negative but was [" + amount + "]")) then it MIGHT make sense to verify, if for given data appropriate exception with appropriate message was thrown

But you are right, this might be overused, and lead to maintenance nightmare.

And BTW. TestNG had this feature for some time, and with nicer syntax

-- Cheers, Tomek Kaczanowski http://kaczanowscy.pl/tomek

Loren Kratzke replied on Tue, 2011/09/27 - 12:39pm in response to: Tomek Kaczanowski

Good point.

Jakub Holý replied on Mon, 2011/10/17 - 3:31am in response to: Tomek Kaczanowski

@Tomek Thank you for a good response! @Loren is right that it makes tests brittle and often it might be better to fix the design instead, e.g. creating a custom exception subclass. However there are certainly cases when this doesn't pay off and using this little dirty check is the best compromise.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.