Unit Testing Spring apps with @RunWith(SpringJUnit4ClassRunner.class)

Thursday, June 24th, 2010

The Problem

I love Spring, who doesn’t?

One thing however that I found, until recently, a bit awkward was Unit Testing objects which were constructed and initiated via the Spring context and injected into other objects that consumed them. I have seen and used many and varied “bespoke” ways to do this, none of which I found satisfying.

This was until a collegue introduced me to the wonder that is SpringJUnit4ClassRunner. I know, I know, I should have been aware of this ages ago but as they say on millionaire “it’s easy if you know the answer”!

Solution

A few lines of code speaks more than a thousand words from me……

package foo.bar;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"daos.xml"})
public final class DaoTests {

    @Autowired
    private MyDao dao;

    @Test
    public void testLoadTitle() throws Exception {
        String result = dao.doSomething();
        assertNotNull(result);
    }
}

Whats going on?

@RunWith(SpringJUnit4ClassRunner.class)
Quoting the docs: “SpringJUnit4ClassRunner is a custom extension of JUnit4ClassRunner which provides functionality of the Spring TestContext Framework to standard JUnit 4.4+ tests by means of the TestContextManager and associated support classes and annotations.”

Basically this means that tests are going to be able to get hold of instantiated beans as defined in the Spring context files (see below).

@ContextConfiguration(locations={“daos.xml”})
This is telling the test where to get the context files containing the bean definitions. Note that if you do not provide any arguments to the annotation then a default will be looked for.

For example: If your class is named foo.bar.DaoTests, the context loader will attempt to load your application context from “classpath:/foo/bar/DaoTests-context.xml”.

@Autowired
This will autowire BY TYPE, beans found in the context. Alternatively you could use @Resource to inject the dependencies by NAME (useful if several beans are of the same type)

Conclusion

Now it’s simply the case of adding a few annotations and a few imports to be able easily write tests which use Spring beans. All in all, a very unobtrusive (and fast) process.

You can leave a response, or trackback from your own site.

Tags: , ,
Posted in: Examples



Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>