Mock tests, Interview questions, Tutorials and Tech news
 
 
Home > Programming / tutorials > Using @BeforeClass in Spring integration Tests

Using @BeforeClass in Spring integration Tests

If you are doing integration testing with your spring environment, you would like to see an end to end test running rather than just simple Junit tests. Unit testing are important but there are occasions in which we really the tire to hit the road and what is really happening with the system

During test, if you may want to set up up test data or some fields like connection pool only once. If you are using simple JUnit tests , then an easy way would be to annotate your methods with @BeforeClass and @AfterClass.  Here is an example of @BeforeClass and @AfterClass

How do you achieve the functionality of @BeforeClass in Spring ?

Now let us say you want to run Spring integration tests and your class is

public class MySpringIntegrationTest extends AbstractDependencyInjectionSpringContextTests {

private static int ID = 1111;

@Autowired
private MyBean myBean;

@BeforeClass
public static void before() {

// all the set up code will come here. for eg connecting to database
}

}

If you run this class,  @BeforeClass will never run.

Reason is that spring’s test classes are based on Junit 3.x framework. @BeforeClass has been introduced with JUnit4. Since your class extends AbstractDependencyInjectionSpringContextTests, Junit 4 functions are never invoked.

You will not see compile time errors because Junit 4 would be in your IDE or project classpath.

How to run Spring tests cases with Junit4 ?

Here is what I did

@RunWith(BlockJUnit4ClassRunner.class)
public class MySpringIntegrationTest extends AbstractDependencyInjectionSpringContextTests {

private static int ID = 1111;

@Autowired
private MyBean myBean;

protected String[] getConfigLocations()
{
return new String[]{“classpath:applicationContext-*.xml”};
}

@BeforeClass
public static void before() {

// all the set up code will come here. for eg connecting to database
}

@Before
final public void callSetup() throws Exception {
super.setUp();
}

@After
public void callTearDown() throws Exception {
super.tearDown();
}

@Test
public void testMethod1_happy() throws Exception{
}

}

You can use @RunWith((TestClassRunner.class) but it has been depreciated. So you better off with @RunWith(BlockJUnit4ClassRunner.class)

What you have done by annotating your class with @RunWith(BlockJUnit4ClassRunner.class) is that you have forced Spring to run with JUnit4 and asked it to ignore JUnit3.

But once you do this, your annotated myBean would be null. Spring would not injected it for you.

Why ?

JUnit 4 only cares about annotations and won’t run the old setUp and tearDown methods defined by the Spring classes. To get around this, add methods with Before and After annotations to call setUp and tearDown.

@Before final public void callSetup() throws Exception {
  super.setUp();
}

@After public void callTearDown() throws Exception {
  super.tearDown();
}

Now your test class with run with Junit4 and base class features are also available.

@BeforeClass and @AfterClass in Junit

Be Sociable, Share!
Categories: Programming / tutorials Tags: ,
  1. January 7th, 2011 at 07:43 | #2

    You are very welcome. I have a blog post nearly ready to go on Spring & JUnit at my site gordondickens dot com.

  2. Sudheer
    January 5th, 2011 at 15:57 | #3

    One more issue with this teh setupbeforeclass annotated method has to be static. What if i want to access my spring beans inside this method ?

    use case : when you are doing integration tests , you will have use cases to stub some other dependency here.

  3. January 5th, 2011 at 14:38 | #4

    Thanks Gordon. That is very helpful.

  4. January 5th, 2011 at 14:11 | #5

    You would be better served by using “SpringJUnit4ClassRunner” which implements BlockJUnit4ClassRunner but adds the following:
    Annotation processing:
    @Autowired – autowiring beans, autowiring the context into the test
    @Transactional – mark a method (or all methods as transactional)

    Additional Annotations:
    @Timed – provide a limit of time the test should not exceed
    @IfProfileValue – support for test profiles
    @Repeat – Repeat a test n number of times
    @BeforeTransaction
    @AfterTransaction
    @DirtiesContext – Mark the app context as dirty (after the test or class) and should be closed

    Regards,
    Gordon Dickens
    twitter.com/gdickens

  5. January 3rd, 2011 at 13:38 | #6

    Yep. TestNG provides a better infrastructure for testing.

  6. Martin Vanek
    January 3rd, 2011 at 12:11 | #7

    …or you can stop hacking flawed inflexible design of JUnit and use TestNG where @BeforeClass annotation can be placed on nonstatic method and happily use spring injected properties in setup code…

  1. No trackbacks yet.

Get Adobe Flash playerPlugin by wpburn.com wordpress themes