Close

Spring Core Testing - Spring JUnit 4 Rules

Spring 4.12 introduced two JUnit rules: SpringClassRule and SpringMethodRule.

Instead of using @RunWith(SpringRunner.class), we can use these two rules to achieve the same result.

As JUnit framework allows only one Runner in a test class, Spring JUnit rules provide the flexibility to run tests in Spring context environment without using @RunWith(SpringRunner.class), which allows us to use other JUnit runners like Parameterized in the same test class.

Deprecation

Spring 7 deprecated SpringClassRule and SpringMethodRule rules because they were tightly coupled to JUnit 4’s Rule model, which had separate and limited hooks for class-level and method-level test lifecycle management. JUnit 5 introduced a more powerful and unified extension model that provides fine-grained lifecycle callbacks, parameter resolution, and better composition. This allowed Spring to consolidate all test context, dependency injection, and lifecycle handling into a single SpringExtension, eliminating the need for multiple rules and providing a cleaner, more flexible, and more maintainable integration.

Example

Creating a simple Spring application

package com.logicbig.example;

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

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

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

    public void addItem(String name, int qty) {
        orders.add(String.format("order. Item:%s qty%s", name, qty));
    }

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

    public String placeOrders() {
        return orders.size() + " orders placed";
    }
}
package com.logicbig.example;

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

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

Writing JUnit test

package com.logicbig.example;

import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.rules.SpringClassRule;
import org.springframework.test.context.junit4.rules.SpringMethodRule;

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

    @ClassRule
    public static final SpringClassRule SPRING_CLASS_RULE= new SpringClassRule();

    @Rule
    public final SpringMethodRule springMethodRule = new SpringMethodRule();

    @Autowired
    private ShoppingCart shoppingCart;

    @Test
    public void testCheckout() {
        shoppingCart.addItem("Item1", 3);
        shoppingCart.addItem("item2", 5);
        String result = shoppingCart.checkout();
        System.out.printf("Shopping cart checkout response: %s%n", result);
        Assert.assertEquals("2 orders placed", result);
    }
}
D:\example-projects\spring-core-testing\spring-core-testing-with-junit-4\spring-junit-rules>mvn -q test
Shopping cart checkout response: 2 orders placed

Note:

As seen in the above example, SpringMethodRule should always be annotated with @Rule and SpringClassRule should always be annotated with @ClassRule. That's because SpringMethodRule supports instance level features, whereas, SpringClassRule supports class level features.

Example Project

Dependencies and Technologies Used:

  • spring-context 4.3.9.RELEASE (Spring Context)
  • spring-test 4.3.9.RELEASE (Spring TestContext Framework)
  • junit 4.12 (JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck)
  • JDK 1.8
  • Maven 3.9.11

spring-junit-rules Select All Download
  • spring-junit-rules
    • src
      • main
        • java
          • com
            • logicbig
              • example
      • test
        • java
          • com
            • logicbig
              • example
                • ShoppingCartTest.java

    See Also

    Join