2014-02-09

JUnit lifecycle

Introduction

JUnit is basic and first tool which is used for testing in Java. JUnit uses annotations to describe lifecycle, but sometimes order of operations executed by this library is not obvious. For example: when constructor of test class is called or when static initalization block is executed?

Main

This JUnit test class will be used to show when methods and blocks are executed.
package com.blogspot.przybyszd.junitlifecycle;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JunitLifecycleTest{
    private static final Logger LOG = LoggerFactory.getLogger(JunitLifecycleTest.class);
    
    static{
        LOG.info("In static initialization block");
    }
    
    public JunitLifecycleTest(){
        LOG.info("In constructor");
    }
    
    {
        LOG.info("In initialization block");
    }
    
    @Test
    public void test1(){
        LOG.info("In test 1");
    }
    
    @Test
    public void test2(){
        LOG.info("In test 2");
    }
    
    @BeforeClass
    public static void oneTimeSetUp(){
        LOG.info("In before class");
    }
    
    @Before
    public void prepareTest(){
        LOG.info("In before");
    }
    
    @After
    public void tearDown(){
        LOG.info("In after");
    }
    
    @AfterClass
    public static void oneTimeTearDown(){
        LOG.info("In after class");
    }
}

And this is output after executing tests from this class.
2014-02-09 17:36:52,931 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:19 - In static initialization block
2014-02-09 17:36:52,935 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:42 - In before class
2014-02-09 17:36:52,936 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:27 - In initialization block
2014-02-09 17:36:52,937 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:23 - In constructor
2014-02-09 17:36:52,938 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:47 - In before
2014-02-09 17:36:52,938 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:32 - In test 1
2014-02-09 17:36:52,938 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:52 - In after
2014-02-09 17:36:52,940 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:27 - In initialization block
2014-02-09 17:36:52,941 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:23 - In constructor
2014-02-09 17:36:52,941 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:47 - In before
2014-02-09 17:36:52,941 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:37 - In test 2
2014-02-09 17:36:52,941 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:52 - In after
2014-02-09 17:36:52,942 [INFO ] com.blogspot.przybyszd.junitlifecycle.JunitLifecycleTest:57 - In after class

As we can see, static initialization block is executed before metchod annotated with BeforeClass. You can initialize here heavy objects, like Hibernate SessionFactory.

Before each test not only method annotated with Before is called. Earlier initialization block and constructor is called. There you can create resources, which should be not shared between tests (for example to get Hibernate Session from SessionFactory).

At the end of each test method annotated with After is called (for example to close Hibernate Session) and at the end of whole class, method annotated with AfterClass could free your resources (for example Hibernate SessionFactory).

Conclusion

It is why JUnit is great for unit testing. State for each test could be created in initial block, constructor of before method and it does not share it between test methods, because for each test new class is created. Of course, You can always store something in static variables, for example heavy objects which You want to create only once.