JUnit: How to not test exceptions

If you’re using JUnit to test your code (and I hope, that you test your code), maybe you want to test a method like the following:

public void someMethod(Object param) {
    if (param == null) throw new IllegalArgumentException("param was null!");
}

JUnit offers a nice way for testing exception, using the expected parameter in the @Test-annotation.

@Test(expected = IllegalArgumentException.class)
public void someTest() {
    someObject.someMethod(null);
}

That’s okay here. But what if …

public void someMethod(Object param) {
    if (param == null) throw new IllegalArgumentException("param was null!");
    throw new IllegalArgumentException("Ooops");
}

Why would someone do this? Don’t ask me. But hey, it’s only an example, you understand what I mean.

The test still runs perfectly. But what if …

… we delete the if (param == null) line? Let’s do this and look … The test still runs. Which is bad. Actually, the test isn’t complete; it tests whether an exception is thrown, but not which.

To do it better, we need a Junit ruleExpectedException. Therefore, we introduce a new field in our testclass:

@Rule public ExpectedException exception = ExpectedException.none();

With that, we can modify our test-case:

@Test
public void someTest() {
    exception.expect(IllegalArgumentException.class);
    exception.expectMessage("param was null!");

    someObject.someMethod(null);
}

That’s much better. It not only checks whether the type of the exception is correct, but it also asserts that the message is correct. That helps us more.

To conclude some very hurting code I’ve seen, not long ago:

@Test(expected = Exception.class)
public void someTest() {
    // Much crazy shit here
    someObject.someMethod(null);
    // More crazy shit here
}

What could possibly go wrong? Everything.

Imagine the first crazy shit is wrong. IOException => Bamm => Test succeeds.

Or: someObject isn’t initialized. NullPointerException => Bamm => Test succeeds.

What happens if your someMethod doesn’t work, but the second crazy shit is broken? AssertionError => Bamm => Test succeeds.

So keep one thing in mind: Never use @Test(expected if you don’t have a good reason to do so.

And test your fucking code.

 

Advertisements
Tagged , , , , , , , ,

2 thoughts on “JUnit: How to not test exceptions

  1. rangerdang3r says:

    Wait, people actually test their code?

    Psh. Just get it right the first time.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: