JUnit Hidden Feature: Enclosed

Posted by Anders Fri, 14 Sep 2007 15:11:00 GMT

When JUnit 4.1 was released last year, they added a nice feature that has gone mostly unnoticed.

RSpec envy

Consider this archetypical RSpec example in Ruby. One class, Stack, being tested in two different scenarios (empty and non-empty):

  describe Stack, " (empty)" do
    before(:each) do
      @stack = Stack.new
    end

    it "should have zero size" do
      @stack.size.should == 0
    end

    # ...
  end

  describe Stack, " (non-empty)" do
    before(:each) do
      @stack = Stack.new
      @stack.push 'x'
    end

    it "should have size greater than zero" do
      @stack.size.should > 0
    end

    # ...
  end

Doing the same thing in JUnit would require us to either create two different classes, which makes our tests hard to follow, or to abandon the “before”-methods and initializing at the start of each test method. Other tools, like JDave, solve this by having an inner class for each scenario, but for various reasons JDave isn’t the solution for me.

Enclosed to the rescue

When browsing the JUnit source code, my colleague Rickard stumbled on the org.junit.runners.Enclosed class. Apparently it’s been part of JUnit since 4.1 released in 2006. Enclosed is a test runner that runs all the inner classes of a class as tests. It works perfectly within IntelliJ and other tools. Now you can have Rspec-style testing in JUnit, almost. Behold its goodness:


@RunWith(org.junit.runners.Enclosed.class)
public class StackTest {

    public static class EmptyStack {
        private Stack stack;

        @Before
        public void before() {
            stack = new Stack();
        }

        @Test
        public void shouldHaveZeroSize() {
            assertEquals(0, stack.size());
        }

        // ...
    }

    public static class NonEmptyStack {
        private Stack stack;

        @Before
        public void before() {
            stack = new Stack();
            stack.push("x");
        }

        @Test
        public void shouldHaveSizeGreaterThanZero() {
            assertTrue(stack.size() > 0);
        }

        // ...
    }
}

Posted in ,  | Tags , , , ,  | 2 comments

RSpec Organization and JUnit Pains

Posted by Anders Sun, 15 Apr 2007 10:07:00 GMT

When I first tried RSpec it felt like a good tool that forced you to write your tests in a form that’s very close to what’s considered best practice. There are a lot of ways to abuse Test::Unit or JUnit, but if you know what you’re doing you’re usually still close. RSpec was good enough for me to change to it, but didn’t feel like a big deal.

But after some time with RSpec I’m now writing a lot tests in Java again. What I realize is how hard it is to organize tests well in JUnit. The tool is fighting me all the way, you just can’t make simple tests easily. If you want to take full advantage of the setUp() methods you have to create a lot of classes. This quickly makes it hard to get an overview over your tests. It just can’t be compared to RSpec’s “context”. I believe JUnit’s way of having exactly one setUp() per class is the problem. Maybe some way of allowing multiple setUp() would be possible.

There are a lot of other differences between RSpec and JUnit, the conditions for example (assertTrue vs. should_eat_cake) and the naming of the test cases. But still the organization of the tests make a big difference. There’s nothing for Java that really does that today. Test NG does an attempt, but at the cost of a little more complexity. But there’s nothing preventing it from being done.

Posted in , ,  | Tags , ,  | 1 comment