Close

Spring - Integration Testing with JUnit 4

[Last Updated: Nov 25, 2025]

As spring beans are nothing but POJOs, we can always write unit test for individual beans that simply instantiated using the new operator, without Spring or any other container. But that's not good enough if we also would like to test whether beans are wired together properly or not and whether everything works as expected when tested in Spring container.

Spring TestContext

The Spring TestContext Framework supports full integration with JUnit through a custom runner.

This example shows how to use TestContext framework with JUnit 4.

Example

Creating a simple Spring application.

AppConfig

package com.logicbig.example;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.logicbig.example")
public class AppConfig {
}

Order

package com.logicbig.example;

public class Order {
  private String item;
  private int qty;

  public Order(String item, int qty) {
      this.item = item;
      this.qty = qty;
  }

  public String getItem() {
      return item;
  }

  public int getQty() {
      return qty;
  }
}

OrderService

package com.logicbig.example;

import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class OrderService {

  public String placeOrders(List<Order> orders) {
      //just a dummy service
      return orders.size() + " orders placed";
  }
}

ShoppingCart

package com.logicbig.example;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ShoppingCart {
  @Autowired
  private OrderService orderService;
  private List<Order> orders = new ArrayList<>();

  public void addItem(String name, int qty) {
      orders.add(new Order(name, qty));
  }

  public String checkout() {
      String msg = orderService.placeOrders(orders);
      orders.clear();
      return msg;
  }
}

Test class

By annotating test classes with @RunWith(SpringJUnit4ClassRunner.class) or the shorter @RunWith(SpringRunner.class) variant, we can write standard JUnit 4 unit and integration tests. That means we can have full support of spring context loading and dependency injection of the beans in our tests.

package com.logicbig.example;

import org.junit.Assert;
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.SpringRunner;

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class ShoppingCartTest {

  @Autowired
  private ShoppingCart shoppingCart;

  @Test
  public void testCheckout() {
      shoppingCart.addItem("Item1", 3);
      shoppingCart.addItem("item2", 5);
      String result = shoppingCart.checkout();
      Assert.assertEquals("2 orders placed", result);
  }
}
mvn test

Output

D:\example-projects\spring-core-testing\spring-testing-getting-started>mvn test
[INFO] Scanning for projects...
[INFO]
[INFO] --------< com.logicbig.example:spring-testing-getting-started >---------
[INFO] Building spring-testing-getting-started 1.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ spring-testing-getting-started ---
[INFO] skip non existing resourceDirectory D:\example-projects\spring-core-testing\spring-testing-getting-started\src\main\resources
[INFO]
[INFO] --- compiler:3.3:compile (default-compile) @ spring-testing-getting-started ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ spring-testing-getting-started ---
[INFO] skip non existing resourceDirectory D:\example-projects\spring-core-testing\spring-testing-getting-started\src\test\resources
[INFO]
[INFO] --- compiler:3.3:testCompile (default-testCompile) @ spring-testing-getting-started ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- surefire:3.2.5:test (default-test) @ spring-testing-getting-started ---
[INFO] Using auto detected provider org.apache.maven.surefire.junit4.JUnit4Provider
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.logicbig.example.ShoppingCartTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.565 s -- in com.logicbig.example.ShoppingCartTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.574 s
[INFO] Finished at: 2025-11-13T20:58:46+08:00
[INFO] ------------------------------------------------------------------------

What is @ContextConfiguration?

This class-level annotation is used to specify what application configuration to load for Spring context. In above example, we specified 'classes' element with the value of our JavaConfig class

What is @RunWith annotation?

If a JUnit class or its parent class is annotated with @RunWith, JUnit framework invokes the specified class as a test runner instead of running the default runner.
See the tutorial on @RunWith

SpringJUnit4ClassRunner vs SpringRunner

Both runners are exactly the same .
SpringRunner was introduce just as a short name.

SpringRunner is a subclass of SpringJUnit4ClassRunner and it does nothing special but just provide a short name to be used with @RunWith.

public final class SpringRunner extends SpringJUnit4ClassRunner {
    public SpringRunner(Class<?> clazz) throws InitializationError {
        super(clazz);
    }
}

SpringRunner was introduced in Spring 4.3.0

In this example we used SpringRunner. Checkout this example of SpringJUnit4ClassRunner.

Example Project

Dependencies and Technologies Used:

  • spring-context 6.2.13 (Spring Context)
     Version Compatibility: 3.2.9.RELEASE - 6.2.13Version List
    ×

    Version compatibilities of spring-context with this example:

    • 3.2.9.RELEASE
    • 3.2.10.RELEASE
    • 3.2.11.RELEASE
    • 3.2.12.RELEASE
    • 3.2.13.RELEASE
    • 3.2.14.RELEASE
    • 3.2.15.RELEASE
    • 3.2.16.RELEASE
    • 3.2.17.RELEASE
    • 3.2.18.RELEASE
    • 4.0.0.RELEASE
    • 4.0.1.RELEASE
    • 4.0.2.RELEASE
    • 4.0.3.RELEASE
    • 4.0.4.RELEASE
    • 4.0.5.RELEASE
    • 4.0.6.RELEASE
    • 4.0.7.RELEASE
    • 4.0.8.RELEASE
    • 4.0.9.RELEASE
    • 4.1.0.RELEASE
    • 4.1.1.RELEASE
    • 4.1.2.RELEASE
    • 4.1.3.RELEASE
    • 4.1.4.RELEASE
    • 4.1.5.RELEASE
    • 4.1.6.RELEASE
    • 4.1.7.RELEASE
    • 4.1.8.RELEASE
    • 4.1.9.RELEASE
    • 4.2.0.RELEASE
    • 4.2.1.RELEASE
    • 4.2.2.RELEASE
    • 4.2.3.RELEASE
    • 4.2.4.RELEASE
    • 4.2.5.RELEASE
    • 4.2.6.RELEASE
    • 4.2.7.RELEASE
    • 4.2.8.RELEASE
    • 4.2.9.RELEASE
    • 4.3.0.RELEASE
    • 4.3.1.RELEASE
    • 4.3.2.RELEASE
    • 4.3.3.RELEASE
    • 4.3.4.RELEASE
    • 4.3.5.RELEASE
    • 4.3.6.RELEASE
    • 4.3.7.RELEASE
    • 4.3.8.RELEASE
    • 4.3.9.RELEASE
    • 4.3.10.RELEASE
    • 4.3.11.RELEASE
    • 4.3.12.RELEASE
    • 4.3.13.RELEASE
    • 4.3.14.RELEASE
    • 4.3.15.RELEASE
    • 4.3.16.RELEASE
    • 4.3.17.RELEASE
    • 4.3.18.RELEASE
    • 4.3.19.RELEASE
    • 4.3.20.RELEASE
    • 4.3.21.RELEASE
    • 4.3.22.RELEASE
    • 4.3.23.RELEASE
    • 4.3.24.RELEASE
    • 4.3.25.RELEASE
    • 4.3.26.RELEASE
    • 4.3.27.RELEASE
    • 4.3.28.RELEASE
    • 4.3.29.RELEASE
    • 4.3.30.RELEASE
    • 5.0.0.RELEASE
    • 5.0.1.RELEASE
    • 5.0.2.RELEASE
    • 5.0.3.RELEASE
    • 5.0.4.RELEASE
    • 5.0.5.RELEASE
    • 5.0.6.RELEASE
    • 5.0.7.RELEASE
    • 5.0.8.RELEASE
    • 5.0.9.RELEASE
    • 5.0.10.RELEASE
    • 5.0.11.RELEASE
    • 5.0.12.RELEASE
    • 5.0.13.RELEASE
    • 5.0.14.RELEASE
    • 5.0.15.RELEASE
    • 5.0.16.RELEASE
    • 5.0.17.RELEASE
    • 5.0.18.RELEASE
    • 5.0.19.RELEASE
    • 5.0.20.RELEASE
    • 5.1.0.RELEASE
    • 5.1.1.RELEASE
    • 5.1.2.RELEASE
    • 5.1.3.RELEASE
    • 5.1.4.RELEASE
    • 5.1.5.RELEASE
    • 5.1.6.RELEASE
    • 5.1.7.RELEASE
    • 5.1.8.RELEASE
    • 5.1.9.RELEASE
    • 5.1.10.RELEASE
    • 5.1.11.RELEASE
    • 5.1.12.RELEASE
    • 5.1.13.RELEASE
    • 5.1.14.RELEASE
    • 5.1.15.RELEASE
    • 5.1.16.RELEASE
    • 5.1.17.RELEASE
    • 5.1.18.RELEASE
    • 5.1.19.RELEASE
    • 5.1.20.RELEASE
    • 5.2.0.RELEASE
    • 5.2.1.RELEASE
    • 5.2.2.RELEASE
    • 5.2.3.RELEASE
    • 5.2.4.RELEASE
    • 5.2.5.RELEASE
    • 5.2.6.RELEASE
    • 5.2.7.RELEASE
    • 5.2.8.RELEASE
    • 5.2.9.RELEASE
    • 5.2.10.RELEASE
    • 5.2.11.RELEASE
    • 5.2.12.RELEASE
    • 5.2.13.RELEASE
    • 5.2.14.RELEASE
    • 5.2.15.RELEASE
    • 5.2.16.RELEASE
    • 5.2.17.RELEASE
    • 5.2.18.RELEASE
    • 5.2.19.RELEASE
    • 5.2.20.RELEASE
    • 5.2.21.RELEASE
    • 5.2.22.RELEASE
    • 5.2.23.RELEASE
    • 5.2.24.RELEASE
    • 5.2.25.RELEASE
    • 5.3.0
    • 5.3.1
    • 5.3.2
    • 5.3.3
    • 5.3.4
    • 5.3.5
    • 5.3.6
    • 5.3.7
    • 5.3.8
    • 5.3.9
    • 5.3.10
    • 5.3.11
    • 5.3.12
    • 5.3.13
    • 5.3.14
    • 5.3.15
    • 5.3.16
    • 5.3.17
    • 5.3.18
    • 5.3.19
    • 5.3.20
    • 5.3.21
    • 5.3.22
    • 5.3.23
    • 5.3.24
    • 5.3.25
    • 5.3.26
    • 5.3.27
    • 5.3.28
    • 5.3.29
    • 5.3.30
    • 5.3.31
    • 5.3.32
    • 5.3.33
    • 5.3.34
    • 5.3.35
    • 5.3.36
    • 5.3.37
    • 5.3.38
    • 5.3.39
    • Compatible Java Version: 17+
    • 6.0.0
    • 6.0.1
    • 6.0.2
    • 6.0.3
    • 6.0.4
    • 6.0.5
    • 6.0.6
    • 6.0.7
    • 6.0.8
    • 6.0.9
    • 6.0.10
    • 6.0.11
    • 6.0.12
    • 6.0.13
    • 6.0.14
    • 6.0.15
    • 6.0.16
    • 6.0.17
    • 6.0.18
    • 6.0.19
    • 6.0.20
    • 6.0.21
    • 6.0.22
    • 6.0.23
    • 6.1.0
    • 6.1.1
    • 6.1.2
    • 6.1.3
    • 6.1.4
    • 6.1.5
    • 6.1.6
    • 6.1.7
    • 6.1.8
    • 6.1.9
    • 6.1.10
    • 6.1.11
    • 6.1.12
    • 6.1.13
    • 6.1.14
    • 6.1.15
    • 6.1.16
    • 6.1.17
    • 6.1.18
    • 6.1.19
    • 6.1.20
    • 6.1.21
    • 6.2.0
    • 6.2.1
    • 6.2.2
    • 6.2.3
    • 6.2.4
    • 6.2.5
    • 6.2.6
    • 6.2.7
    • 6.2.8
    • 6.2.9
    • 6.2.10
    • 6.2.11
    • 6.2.12
    • 6.2.13

    Versions in green have been tested.

  • spring-test 6.2.13 (Spring TestContext Framework)
  • junit 4.13.2 (JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck)
  • JDK 25
  • Maven 3.9.11

Spring Testing - Using Spring TestContext Framework Select All Download
  • spring-testing-getting-started
    • src
      • main
        • java
          • com
            • logicbig
              • example
      • test
        • java
          • com
            • logicbig
              • example
                • ShoppingCartTest.java

    See Also