Charlie's super short JUnit 4 tips

Tagged:
JUnit 4 stuff, may be old to many, but I have to refer back to my own list once in a while, so here goes:

  • 1. HOWTO - FAIL when exception occurs - just throw it (same as older JUnit)
  • @Test
    public void testIndexOutOfBoundsExceptionNotRaised()
             throws IndexOutOfBoundsException
             ArrayList emptyList = new ArrayList();
             Object o = emptyList.get(0);
         }
    
  • 2. HOWTO - SUCCEED when exception occurs - expecting it, don't have to catch and ignore
  • @Test(expected=IndexOutOfBoundsException.class)
         public void testIndexOutOfBoundsException() {
             ArrayList emptyList = new ArrayList();
            Object o = emptyList.get(0);
         }
    
  • 3. HOWTO - ignore a test - failing for a reason out of your control, takes too long, don't want it to be part of build but do want to run it individually, etc
  • @Ignore
    
  • 4. HOWTO - timed tests - keep in mind that your tests may run twice though,if you are using code coverage and instrumenting - those will be slower and can affect your timings.
  • @Test(timeout=500)
    
  • 5. HOWTO - run a test X times repeatedly
  • Make your own runner, and use it to run:
    public static class MultiRunner extends JUnit4ClassRunner {
       public MultiRunner(Class clazz) throws InitializationError {
         super(clazz);
       }
       @Override
       public void run(final RunNotifier notifier) {
         for(int i=0; i<1000; i++) {
           super.run(notifier);
         }
       }
    }
    
    @RunWith(MultiRunner.class)
    public class MultiRunTest {
    
    }
    
  • 6. TIP - Use Hamcrest matchers
  • JUnit 4.4 and up has "assertThat" for use with the Hamcrest matchers. This makes for easier/shorter assertions, and they read more like sentences.

    http://junit.sourceforge.net/javadoc_40/org/junit/Assert.html#assertThat(T,%20org.hamcrest.Matcher)

    You can use these "matchers" with assertThat: http://code.google.com/p/hamcrest/wiki/Tutorial
    http://junit.sourceforge.net/javadoc_40/org/junit/matchers/JUnitMatchers.html

    Have to include Hamcrest as a "test" scope dep for this.

  • 7. FAQ - Should getters and setters and other trivial stuff be tested?
  • Many opinions on this, the basic answer though is test what you think needs testing - http://junit.sourceforge.net/doc/faq/faq.htm#tests_5.

    "Test until fear becomes boredom."

    In general, getters and setters can be an anti-pattern unless you really are using property style handling with JavaBeans (rather than just saying "create getters and setters" in your IDE). So the first rule is DON'T HAVE GETTERS AND SETTERS unless absolutely needed. Then the second rule is that some other code should exercise those in general, so the probably don't need explicit tests - UNLESS they do some weird state changing stuff and aren't vanilla getters/setters (but that's also usually a bad idea).

    Using those two rules, if you run coverage and you see getters and setters that aren't covered, 98% of the time it's because you don't need them at all, not because you forgot to test them. (Though the exception here is test first development, then you have to consider them a bit more.)

  • 8. Should private methods be tested?
  • Same deal, if you are more comfortable when they are tested, then yes. Also, if you really do test FIRST development, which has advantages (but not everyone likes it), that is when this really comes up. You can use reflection or groovy to test these. If you don't do test first then usually your other code should indeed exercise the private methods.

    http://www.onjava.com/pub/a/onjava/2003/11/12/reflection.html

    Comments

    Getters and Setters

    So the first rule is DON'T HAVE GETTERS AND SETTERS unless absolutely needed. This is a bad rule in my opinion. Needed is needed, what is absolutely needed? Exposing your instance variables should be the exception, not the rule.

    accessor/mutator rule

    I certainly didn't mean you should expose instance variables in general (though it actually performs better for internal classes, often, depends on the situation and context). And yes "absolutely" is bad wording. What I meant though, is many people often just use the IDE to gen the accessors/mutators even when they never use them - and or they think that's the only way to expose state when often other patterns are much better for the job (again, depends on context). See many anti-patterns JavaBeans articles for more info: http://www.javapractices.com/topic/TopicAction.do?Id=84.

    Comment viewing options

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