Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Dependency Injection with Spring Boot Unit Testing?

Is it possible to use dependency injection with unit tests using Spring Boot? For integration testing @SpringBootTest start the whole application context and container services. But is it possible to enable dependency injection functionality at unit test granularity?

Here's the example code

@ExtendWith(SpringExtension.class)
public class MyServiceTest {
    
    @MockBean
    private MyRepository repo;
    
    @Autowired
    private MyService service; // <-- this is null
    
    @Test
    void getData() {
        MyEntity e1 = new MyEntity("hello");
        MyEntity e2 = new MyEntity("world");
        
        Mockito.when(repo.findAll()).thenReturn(Arrays.asList(e1, e2));
        
        List<String> data = service.getData();
        
        assertEquals(2, data.size());
    }
}

@Service
public class MyService {
    
    private final MyRepository repo; // <-- this is null
    
    public MyService(MyRepository repo) {
        this.repo = repo;
    }
    
    public List<String> getData() {
        return repo.findAll().stream()
                .map(MyEntity::getData)
                .collect(Collectors.toList());
    }
}

Or should I just manage the SUT (service class) as POJO and manually inject the mocked dependencies? I want to keep tests fast but minimize boilerplate code.

like image 669
Tuomas Toivonen Avatar asked Feb 23 '26 22:02

Tuomas Toivonen


1 Answers

As @M.Deinum mentioned in the comments, unit tests shouldn't use dependency injection. Mock MyRepository and inject MyService using Mockito (and Junit5):

@ExtendWith(MockitoExtension.class)
public class MyServiceTest {

    @InjectMocks
    private MyService service;

    @Mock
    private MyRepository repo;

    @Test
    void getData() {
        MyEntity e1 = new MyEntity("hello");
        MyEntity e2 = new MyEntity("world");

        Mockito.when(repo.findAll()).thenReturn(Arrays.asList(e1, e2));

        List<String> data = service.getData();

        assertEquals(2, data.size());
    }
}

If you want to test the repository, use @DataJpaTest. From the docs:

Using this annotation will disable full auto-configuration and instead apply only configuration relevant to JPA tests.

@DataJpaTest
public class MyRepositorTest {

    @Autowired
    // This is injected by @DataJpaTest as in-memory database
    private MyRepository repo;

    @Test
    void testCount() {
        repo.save(new MyEntity("hello"));
        repo.save(new MyEntity("world"));

        assertEquals(2, repo.count());
    }
}

In conclusion, the suggested approach is to test the service layer mocking the repository layer with Mockito (or similar library) and to test the repository layer with @DataJpaTest.

like image 91
Marc Avatar answered Feb 25 '26 11:02

Marc



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!