JUnit Hidden Feature: Enclosed

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);
        }

        // ...
    }
}

Update: Enclosed was moved to junit.experimental.runners.Enclosed in later JUnit versions.

About these ads
This entry was posted in bdd, Java, jdave, junit, Programming, rspec, testing. Bookmark the permalink.

2 Responses to JUnit Hidden Feature: Enclosed

  1. Klaus Meffert says:

    Hmm, this example seems sort of artificial to me as it could be easily rewritten using two test methods.

  2. Anders says:

    Yes, it is artificial, that’s what makes it an example. ;)

    Seriously though, in real code you’d have a lot of test methods on each scenario, so you wouldn’t want to repeat the setup code in every method.

Comments are closed.