spring-projects / spring-projects/spring-framework

Provide guidance on using `@Nested` within test classes with complex inheritance and annotation arrangements

Open
#28,466 6 comments 2 reactions 1 assignee View on GitHub

@sbrannen is already working on this.

Since Oct 13, 2025.

in: test type: documentation
Dominant language
Java
Stars
60.2k
Forks
38.8k
Avg merge
5d 2h
Merged PRs (30d)
27

Description

Overview

I've provided a minimal JUnit Jupiter test ConcreteServiceTest reproducing the problem. Please check the code first. The issue is that the mock is not reset so the second test fails since there are 2 calls instead of the expected 1. The use case has a common base service and similarly base test class.

Some observations:

  • If the @Import(ConcreteService.class) is moved on top of the base class the tests pass.
  • If the tests are flattened (not using @Nested test class) then the tests pass.
  • @AfterEach void clearMocks() { reset(dependency); } would make the tests pass as well. I've chosen this as the simplest workaround for the time being (assuming the issue will be fixed and then the method will be simply deleted instead of altering the structure of my code).

Spring Boot version: 2.6.2

import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import static org.mockito.Mockito.verify;

@Import(ConcreteService.class)
class ConcreteServiceTest extends BaseServiceTest {
}

@ExtendWith(SpringExtension.class)
abstract class BaseServiceTest {

    @MockBean
    private Runnable dependency;
    @Autowired
    private BaseService service;

    @Nested
    class Suite {

        @RepeatedTest(2)
        void test() {
            service.serve();

            verify(dependency).run();
        }
    }
}

class ConcreteService extends BaseService {
}

abstract class BaseService {

    @Autowired
    private Runnable dependency;

    public void serve() {
        dependency.run();
    }
}

Related Issues

  • #34906
  • #35894

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.