Backend Development 9 min read

A Minimalist Guide to Setting Up Unit Tests in Spring Boot

This article presents a concise, beginner-friendly approach to building a Spring Boot unit testing environment using only essential Maven dependencies and test classes, covering both integration-style and pure unit test techniques, complete with annotated examples and practical testing tips.

JD Retail Technology
JD Retail Technology
JD Retail Technology
A Minimalist Guide to Setting Up Unit Tests in Spring Boot

This article provides a minimalist unit‑testing method aimed at beginners, showing how to create a functional unit‑testing environment with only the necessary Maven dependencies and test classes in a locally runnable Spring Boot project.

Contents include:

POM dependencies

Unit‑test class examples

Unit‑testing experience summary

POM dependencies

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>3.12.4</version>
</dependency>

1. Integration‑style unit tests – require the application context to start and may connect to databases or RPC registries. Key annotations:

@SpringBootTest + @RunWith(SpringRunner.class) – launch a Spring Boot test environment.

@Transactional – rolls back database changes after each test.

@Resource – inject the class under test.

@SpyBean – mock beans within the Spring context.

@Test – mark a test method.

Example:

/**
 * @author jiangbo8
 * @since 2024/4/24 9:52
 */
@Transactional
@SpringBootTest
@RunWith(SpringRunner.class)
public class SalesAmountPlanControllerAppTest {
    @Resource
    private SalesAmountPlanController salesAmountPlanController;
    @SpyBean
    private ISaleAmountHourHistoryService saleAmountHourHistoryServiceImpl;
    @SpyBean
    private ISaleAmountHourForecastService saleAmountHourForecastServiceImpl;
    @SpyBean
    private ISaleAmountHourPlanService saleAmountHourPlanServiceImpl;

    @Test
    public void testGraph1()  {
        // real call without mock
        SalesAmountDTO dto = new SalesAmountDTO();
        dto.setDeptId1List(Lists.newArrayList(35));
        dto.setDeptId2List(Lists.newArrayList(235));
        dto.setDeptId3List(Lists.newArrayList(100));
        dto.setYoyType(YoyTypeEnum.SOLAR.getCode());
        dto.setShowWeek(true);
        dto.setStartYm("2024-01");
        dto.setEndYm("2024-10");
        dto.setTimeDim(GraphTimeDimensionEnum.MONTH.getCode());
        dto.setDataType(SalesAmountDataTypeEnum.AMOUNT.getCode());
        Result
result = salesAmountPlanController.graph(dto);
        System.out.println(JSON.toJSONString(result));
        Assert.assertNotNull(result);
    }

    @Test
    public void testGraph11()  {
        // mock behavior
        Mockito.doAnswer(this::mockSaleAmountHourHistoryListQuery)
               .when(saleAmountHourHistoryServiceImpl).listBySaleAmountQueryBo(any());
        Mockito.doAnswer(this::mockSaleAmountHourPlansListQuery)
               .when(saleAmountHourPlanServiceImpl).listBySaleAmountQueryBo(any());
        Mockito.doAnswer(this::mockSaleAmountHourForecastListQuery)
               .when(saleAmountHourForecastServiceImpl).listBySaleAmountQueryBo(any());
        // ... (rest of test setup)
        Result
result = salesAmountPlanController.graph(dto);
        System.out.println(JSON.toJSONString(result));
        Assert.assertNotNull(result);
    }

    private List
mockSaleAmountHourHistoryListQuery(org.mockito.invocation.InvocationOnMock s) {
        // mock implementation returning fabricated data
        // ... (omitted for brevity)
        return historyList;
    }
}

2. Pure unit tests – do not start the Spring context and avoid external dependencies; all collaborators are mocked. Key annotations:

@InjectMocks – creates the class under test and injects @Mock fields.

@Mock – defines mock collaborators.

@Test – marks a test method.

Example:

/**
 * Created by jiangbo8 on 2022/10/17 15:02
 */
public class CheckAndFillProcessorTest {
    @Mock Logger log;
    @Mock OrderRelService orderRelService;
    @Mock VenderServiceSdk venderServiceSdk;
    @Mock AfsServiceSdk afsServiceSdk;
    @Mock PriceServiceSdk priceServiceSdk;
    @Mock ProductInfoSdk productInfoSdk;
    @Mock OrderMidServiceSdk orderMidServiceSdk;
    @Mock OrderQueueService orderQueueService;
    @Mock SendpayMarkService sendpayMarkService;
    @Mock TradeOrderService tradeOrderService;

    @InjectMocks
    CheckAndFillProcessor checkAndFillProcessor;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testProcess2() throws Exception {
        OrderRel orderRel = new OrderRel();
        orderRel.setSopOrderId(1111111L);
        orderRel.setVenderId("123");
        when(orderRelService.queryOrderBySopOrderId(anyLong())).thenReturn(orderRel);
        // additional mock setups omitted for brevity
        OrderQueue orderQueue = new OrderQueue();
        orderQueue.setSopOrderId(1111111L);
        DispatchResult result = checkAndFillProcessor.process(orderQueue);
        Assert.assertNotNull(result);
    }
}

3. Unit‑testing experience summary

The author shares practical scenarios where unit tests add value: during refactoring, they provide a safety net to verify behavior unchanged; for new features, a mix of integration‑style and pure unit tests balances coverage and effort; and the emphasis is on quality over raw coverage metrics.

END

Javaunit testingmockingSpring BootJunitMockitoIntegration Test
JD Retail Technology
Written by

JD Retail Technology

Official platform of JD Retail Technology, delivering insightful R&D news and a deep look into the lives and work of technologists.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.