Unitils and the class that had no default constructor

Unitils is so helpful for unit testing.  The top portion of my unit tests tend to look something like this:

@RunWith(UnitilsJUnit4TestClassRunner.class)
public class BongoTest {
    @Mock
    @InjectIntoByType
    private Foo foo;

    @Mock
    @InjectIntoByType
    private Baz baz;

    @TestedObject
    private Bongo bongo;

    //...

And then Unitils automatically instantiates a Bongo and injects the Foo and Baz mocks into the Bongo’s fields of those respective types.  My @Test methods can just start testing Bongo’s methods without worrying about the mock creation and injection and tested object instantiation.  I’m free to get right to testing Bongo out.  Nice!

This time, though, there was a twist: my TestedObject (call it a Congo) didn’t have a default constructor — instead, it needed a Foo and a Baz passed to its constructor.  How to do that with the annotations?

On the Unitils cookbook page, it says:

The field annotated with @TestedObject is automatically instantiated with an instance of the declared type, if necessary (i.e. if not instantiated during test setup) and possible (i.e. if the declared type is a non-abstract class and offers an empty constructor).

So it looks like I have to take on a little responsibility myself this time.  It ends up looking like this (notice the new @Before method):

@RunWith(UnitilsJUnit4TestClassRunner.class)
public class CongoTest {
    @Mock
    private Foo foo;

    @Mock
    private Baz baz;

    @TestedObject
    private Congo congo;

    @Before
    public void setUp() {
        congo = new Congo(foo, baz);
    }
    //...

(Everything else is as, er… Before.)

That’s not too bad!

NullPointerException on my test’s first use of a mock

This had happened before, but it got me again the other day: I was using Unitils‘ mock annotations (great stuff!) to set up my mocks, but my test failed with a NullPointerException the first place I tried to set an expection on the mock.  The reason being… I forgot to @RunWith(UnitilsJUnit4TestClassRunner.class) .  Sadly, I don’t think I was much faster diagnosing the problem this time than I was last time.

Goal: Next time this symptom appears, instantly suspect that I’m using the wrong runner!  :)

Running with the…

(For some reason, “Running with the bulls” sounds a lot more poetic than “Running with the right JUnit 4 test runner.”)

I was getting a NullPointerException when I started writing the unit test for my little TransactionManager wrapper class.  I am using Unitils to manage all the dependency injection, so my test class looks something like this:


public class TransactionManagerTest {
    @Mock
    @InjectIntoByType
    private PlatformTransactionManager platformTransactionManager;

    @TestedObject
    private TransactionManager transactionManager;

    @Test
    public void testCommitException() {
        transactionManager.commit();
    }

I first got the NullPointerException while trying to test TransactionManager’s getTransaction() method, but it has some more complex logic, so I decided to back off from that and test the commit() method first.

I had expected that when I called transactionManager.commit(), I would get the unchecked exception that commit() throws when you haven’t called getTransaction() first.  But instead, this NullPointerException.

Before looking at the answer, can you guess why that would be?

Oh, wait, I already gave it away at the top of this post. Rats!

(Maybe there’s a reason I’m a programmer instead of a game show host. ;)

Yup, that’s right, folks!  All it was, was, I needed to…


@RunWith(UnitilsJUnit4TestClassRunner.class)

See ya next time!