Backend Development 8 min read

Guidelines for Writing Unit Tests with Mockito and Test Case Design in SpringBoot

The article outlines how to design robust SpringBoot unit tests by first mastering business flows and external dependencies, preparing isolated test data, using Mockito’s @Mock/@MockBean and @Spy/@SpyBean correctly—including proper stubbing techniques—and applying best‑practice rules and the ACTS 2.0 framework for data‑driven, coverage‑verified testing.

Ant R&D Efficiency
Ant R&D Efficiency
Ant R&D Efficiency
Guidelines for Writing Unit Tests with Mockito and Test Case Design in SpringBoot

Effective code design should follow the principle of easy modification, which requires frequent refactoring rather than large‑scale rewrites after code becomes bloated. To ensure that frequent changes do not break existing functionality, a comprehensive suite of test cases must be written to cover all execution paths.

The article emphasizes three preparatory steps before writing unit tests:

Fully understand the business flow, including normal and exceptional scenarios.

Identify all external interactions and data mutation points such as RPC calls, MQ messages, and database operations.

Prepare test data that does not affect real production data and can be easily cleaned up.

When writing tests in a SpringBoot environment, Mockito annotations are recommended. The following annotations are available:

@Mock and @MockBean – create mock objects; @MockBean registers the mock as a Spring bean.

@Spy and @SpyBean – create spy objects that call real methods unless stubbed; @SpyBean registers the spy as a Spring bean.

Key differences:

Mocks are not managed by Spring, while @MockBean and @SpyBean are Spring‑managed beans and can be autowired.

When using @Spy , real methods are invoked by default; to stub a method you must use Mockito.doReturn(...).when(...) instead of when(...).thenReturn(...) .

Example of stubbing a method return value:

/ 声明userService在传入任意参数调用get()方法时,返回user
Mockito.when(userService.get(Mockito.any())).thenReturn(user);
Mockito.doReturn(user).when(userService).get(Mockito.any());    // Spy必须用这种

Example of stubbing an exception:

// 声明userService在传入任意参数调用get()方法时,抛出指定异常
Mockito.when(userService.get(Mockito.any())).thenThrow(new RuntimeException("mock error"));
Mockito.doThrow(new RuntimeException("mock error")).when(userService).get(Mockito.any()); // Spy必须用这种

Test cases should focus on internal logic without involving upstream or downstream services. For example, a transfer interface test should verify the synchronous acceptance process and treat asynchronous settlement as a separate test.

Additional best practices include:

Do not let tests modify external applications or real data.

Separate test data using unique identifiers (e.g., id, requestNo) and ensure cleanup scripts only affect test records.

Use coverage tools (e.g., Maven/Gradle coverage mode) to verify test completeness.

The article also introduces the ACTS (AntCoreTestSuite) 2.0 framework, an internal Ant Group solution for data‑driven automated testing of SOFA/SOFABoot services. ACTS provides a standardized lifecycle, visual test case editing, and fine‑grained result verification, dramatically reducing test code size.

Key components of ACTS include:

Test case directory structure (PrepareDBData for initial data, CheckDBData for verification).

Data files describe table columns, data types, primary keys, and a flag indicating insert, check, or cleanup actions.

During verification, ensure the cleanup flag (C) only deletes test data.

Running tests in coverage mode generates detailed coverage reports, helping developers identify untested code paths.

software testingtest automationunit testingmockingtest case designSpringBootMockito
Ant R&D Efficiency
Written by

Ant R&D Efficiency

We are the Ant R&D Efficiency team, focused on fast development, experience-driven success, and practical technology.

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.