JUnit Test Cases @Before @BeforeClass Annotation

โšก Smart Summary

JUnit is the most widely used unit testing framework for Java, and its test fixture annotations control exactly what happens before and after every test method runs inside a test class.

  • ๐Ÿ”˜ Fixture: A test fixture is the fixed context of objects and resources a test case runs in.
  • โ˜‘๏ธ Setup: @Before runs before every test method, while @BeforeClass runs once before the whole class.
  • โœ… Teardown: @After runs after every test, even when the test throws or an assertion fails.
  • ๐Ÿงช Order: Superclass @Before runs first, then subclass @Before, the @Test, then each @After.
  • ๐Ÿ› ๏ธ Runner: JUnitCore.runClasses() executes test classes and returns a Result object holding every failure.
  • ๐Ÿ“Š JUnit 5: @Before, @After, @BeforeClass and @AfterClass become @BeforeEach, @AfterEach, @BeforeAll and @AfterAll.

JUnit test fixture with @Before and @BeforeClass annotations

JUnit is the most popular unit Testing framework in Java. It is explicitly recommended for Unit Testing. JUnit does not require a server to test a web application, which makes the testing process fast.

The JUnit framework also allows quick and easy generation of test cases and test data. The org.junit package consists of many interfaces and classes for JUnit testing, such as Test, Assert, After and Before. The wider JUnit family builds on these same building blocks.

What is a Test Fixture?

Before we understand what a test fixture is, let’s study the code below.

This code is designed to execute two test cases on a simple file.

public class OutputFileTest {
    private File output; 
    output = new File(...);
    output.delete(); 
public void testFile1(){
        //Code to verify Test Case 1
}
    output.delete();
    output = new File(...);
public void testFile2(){
        //Code to verify Test Case 2
}
 output.delete(); 
}

Few issues here

  • The code is not readable.
  • The code is not easy to maintain.
  • When the test suite is complex the code could contain logical issues.

Compare the same code using JUnit.

public class OutputFileTest		
{
    private File output; 
    @Before public void createOutputFile() 
    { 
       output = new File(...);
    }
  
	@After public void deleteOutputFile() 
    {
        output.delete(); 
    } 
     
    @Test public void testFile1() 
    {
       // code for test case objective
    } 
	@Test public void testFile2() 
    {
       // code for test case objective
    }
}

The code is far more readable and maintainable. The above code structure is a test fixture.

A test fixture is a context where a JUnit Test Case runs. Typically, test fixtures include:

  • Objects or resources that are available for any test case.
  • Activities required that make these objects and resources available.
  • These activities are
    1. allocation (setup)
    2. de-allocation (teardown).

Setup and Teardown

Fixtures matter because JUnit runs these hooks around every test.

  • Usually, there are some repeated tasks that must be done prior to each test case. Example: create a database connection.
  • Likewise, at the end of each test case, there may be some repeated tasks. Example: to clean up once test execution is over.
  • JUnit provides annotations that help in setup and teardown. It ensures that resources are released, and the test system is in a ready state for the next test case.

These JUnit annotations are discussed below.

Setup

@Before annotation in JUnit is used on a method containing Java code to run before each test case, that is, it runs before each test execution.

Teardown (regardless of the verdict)

@After annotation is used on a method containing Java code to run after each test case. These methods will run even if any exceptions are thrown in the test case or in the case of assertion failures.

Note:

  • It is allowed to have any number of annotations listed above.
  • All the methods annotated with @Before in JUnit will run before each test case, but they may run in any order.
  • You can inherit @Before and @After methods from a super class. Execution is as follows, and it is a standard execution process in JUnit.
  1. Execute the JUnit @Before methods in the superclass
  2. Execute the @Before methods in this class
  3. Execute a @Test method in this class
  4. Execute the @After methods in this class
  5. Execute the @After methods in the superclass

JUnit 5 note: these annotations are JUnit 4 (org.junit). JUnit 5 renamed them in org.junit.jupiter.api, and the JUnit 4 code below still runs under the vintage engine.

JUnit 4 annotation JUnit 5 (Jupiter) equivalent Runs
@Before @BeforeEach Before every test method
@After @AfterEach After every test method
@BeforeClass @BeforeAll Once before the whole class
@AfterClass @AfterAll Once after the whole class
@Ignore @Disabled Skips the annotated test

Example: Creating a class with file as a test fixture

public class OutputFileTest		
{
    private File output; 
    @Before	public void createOutputFile() 
    { 
       output = new File(...);
    }
  
	@After public void deleteOutputFile() 
    {
        output.delete(); 
    } 
     
    @Test public void testFile1() 
    {
       // code for test case objective
    } 
	@Test public void testFile2() 
    {
       // code for test case objective
    }
}

In the above example the chain of execution will be as follows. The diagram traces one create-test-delete cycle per test method.

JUnit @Before and @After execution chain around two test methods

  1. createOutputFile()
  2. testFile1()
  3. deleteOutputFile()
  4. createOutputFile()
  5. testFile2()
  6. deleteOutputFile()

Assumption:

testFile1() runs before testFile2(), which is not guaranteed.

Once-only setup

  • It is possible to run a method only once for the entire test class before any of the tests are executed, and prior to any @Before method(s).
  • “Once-only setup” is useful for starting servers, opening communications, and similar work. It is time-consuming to close and re-open resources for each test.
  • This can be done using the annotation @BeforeClass in JUnit.
@BeforeClass public static void Method_Name() {	
    // class setup code here	
 }	

The method must be public static void, because JUnit calls it before any test instance exists.

Once-only tear down

  • Similar to once-only setup, a once-only cleanup method is also available. It runs after all test case methods and @After annotations have been executed.
  • It is useful for stopping servers and closing communication links.
  • This can be done using the @AfterClass annotation.
 @AfterClass public static void Method_Name()	
 {	
    // class cleanup code here	
 }	

JUnit Test Suites

With fixtures in place, related test classes are usually grouped and launched together.

If we want to execute multiple tests in a specified order, it can be done by combining all the tests in one place. This place is called a test suite. More details on how to execute test suites and how they are used in JUnit are covered in this tutorial.

JUnit Test Runner

JUnit provides a tool for execution of your test cases.

  • JUnitCore class is used to execute these tests.
  • A method called runClasses provided by org.junit.runner.JUnitCore is used to run one or several test classes.
  • Return type of this method is the Result object (org.junit.runner.Result), which is used to access information about the tests. See the following code example for more clarity.
public class Test {				
			public static void main(String[] args) {									
       		Result result = JUnitCore.runClasses(CreateAndSetName.class);					
			for (Failure failure : result.getFailures()) {							
         		System.out.println(failure.toString());					
      }		
      System.out.println(result.wasSuccessful());					
   }		
}      

In the above code the “result” object is processed to get failures and successful outcomes of the test cases we are executing. Helpers such as assertEquals raise those failures, while @Ignore skips a test.

JUnit 5 note: JUnitCore is the JUnit 4 runner. JUnit 5 replaces it with the JUnit Platform Launcher API, normally started by the IDE, Gradle or Maven Surefire.

First JUnit Program

Fair knowledge of SDLC, Java programming, and the basics of the software testing process helps in understanding a JUnit program, as does knowing how unit tests differ from integration tests.

Let’s understand unit testing using a live example. We need to create a test class with a test method annotated with @Test as given below:

MyFirstClassTest.java

package guru99.JUnit;		

import static org.junit.Assert.*;				

import org.junit.Test;		

public class MyFirstClassTest {				

    @Test		
    public void myFirstMethod(){					
        String str= "JUnit is working fine";					
        assertEquals("JUnit is working fine",str);					
    }
}		

TestRunner.java

To execute our test method (above), we need to create a test runner. In the test runner we have to add the test class as a parameter in JUnitCore’s runClasses() method. It will return the test result, based on whether the test is passed or failed.

For more details on this see the code below:

package guru99.JUnit;		

import org.junit.runner.JUnitCore;		
import org.junit.runner.Result;		
import org.junit.runner.notification.Failure;		

public class TestRunner {				
			public static void main(String[] args) {									
            Result result = JUnitCore.runClasses(MyFirstClassTest.class);					
			for (Failure failure : result.getFailures()) {							
              System.out.println(failure.toString());					
      }		
      System.out.println("Result=="+result.wasSuccessful());							
   }		
}      	

Output

Once TestRunner.java executes our test methods we get output as failed or passed. Please find below the output explanation:

  1. In this example, after executing MyFirstClassTest.java, the test is passed and the result is in green.
  2. If it had failed it would have shown the result as red, and the failure can be observed in the failure trace. See the JUnit GUI below:

Eclipse JUnit view showing a green pass bar for MyFirstClassTest

FAQs

JUnit creates a fresh instance of the test class for every test method, so no instance exists when class-level code must run. Declaring the method static lets JUnit invoke it directly.

No. Method order is deliberately unspecified. JUnit 4 offers @FixMethodOrder and JUnit 5 offers @TestMethodOrder, but depending on order signals coupled tests.

The test method is never invoked and is reported as an error, not a failure. Any @After method still runs, so cleanup must tolerate a partially built fixture.

New projects should add the JUnit 5 aggregate artifact org.junit.jupiter:junit-jupiter. Teams holding legacy JUnit 4 suites add junit-vintage-engine so both run on one platform.

A fixture is the whole prepared context around a test, including real files or connections. A mock is one stand-in collaborator with scripted behaviour, often created by the fixture.

Yes, through @BeforeClass in JUnit 4 or @BeforeAll in JUnit 5. Shared fixtures are faster but leak state, so reserve them for expensive read-only resources.

AI assistants read a class, infer the collaborators it needs, and draft the @Before setup with matching @After cleanup. Always review the generated assertions yourself.

GitHub Copilot scaffolds a test class from a method signature, including lifecycle annotations. It often defaults to JUnit 4 imports, so confirm the package matches your engine.

Summarize this post with: