You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring @Service测试报错:UnsatisfiedDependencyException依赖注入异常

解决Spring @Service测试时的依赖不满足问题

我太懂你这个坑了——测试带JPA Repository依赖的Service时,Spring容器找不到对应的Repository实例,直接抛出UnsatisfiedDependencyException对吧?别慌,给你几个实用的解决办法,按需选就行:

方法1:用切片测试快速验证Service与Repository的交互

如果想验证Service和Repository的实际交互逻辑,又不想启动完整的应用上下文,可以用Spring Boot提供的切片测试注解。@DataJpaTest会自动配置JPA相关组件(包括你的Repository),再通过@Import把Service导入测试上下文,就能解决依赖问题。

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;

import static org.junit.jupiter.api.Assertions.assertNotNull;

@DataJpaTest
@Import(PersonneService.class) // 将Service注入测试上下文
public class PersonneServiceTest {

    @Autowired
    private PersonneService personneService;

    @Autowired
    private PersonneRepository personneRepository;

    @Test
    void createPersonne_ShouldSaveSuccessfully() {
        Personne testPerson = new Personne();
        testPerson.setName("Alice");

        Personne savedPerson = personneService.createPersonne(testPerson);

        assertNotNull(savedPerson.getId()); // 验证保存后生成了主键
    }
}

这种方式会使用嵌入式H2数据库,适合快速验证数据持久化逻辑。

方法2:用Mockito模拟Repository做纯单元测试

如果只想测试Service的业务逻辑(不需要真正操作数据库),可以用Mockito模拟Repository实例,完全脱离Spring容器运行测试,速度更快。

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

@ExtendWith(MockitoExtension.class)
public class PersonneServiceUnitTest {

    @Mock // 模拟Repository实例
    private PersonneRepository personneRepository;

    @InjectMocks // 自动将mock的Repository注入到Service中
    private PersonneService personneService;

    @Test
    void createPersonne_ShouldReturnSavedPerson() {
        Personne inputPerson = new Personne();
        inputPerson.setName("Bob");

        Personne mockSavedPerson = new Personne();
        mockSavedPerson.setId(1L);
        mockSavedPerson.setName("Bob");

        // 定义Repository.save方法的返回值
        when(personneRepository.save(inputPerson)).thenReturn(mockSavedPerson);

        Personne result = personneService.createPersonne(inputPerson);

        assertEquals(mockSavedPerson.getId(), result.getId());
        verify(personneRepository, times(1)).save(inputPerson); // 验证方法调用次数
    }
}

方法3:用完整集成测试覆盖全上下文

如果需要测试整个应用的完整上下文(比如Service还有其他依赖组件),可以用@SpringBootTest启动完整的Spring应用上下文。

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.assertNotNull;

@SpringBootTest
public class PersonneServiceFullIntegrationTest {

    @Autowired
    private PersonneService personneService;

    @Test
    void createPersonne_ShouldPersistToDatabase() {
        Personne personne = new Personne();
        personne.setName("Charlie");

        Personne saved = personneService.createPersonne(personne);

        assertNotNull(saved.getId());
    }
}

这种方式测试范围最广,但启动速度较慢,适合端到端的场景验证。

额外注意点

  • 确保你的PersonneRepository接口正确继承了JpaRepository,或者添加了@Repository注解,Spring才能自动生成代理Bean。
  • 如果用嵌入式数据库,Spring Boot Test会自动配置默认的H2数据库,无需额外配置;如果需要自定义,可以在application-test.yml中配置数据库连接信息。

内容的提问来源于stack exchange,提问作者shmoolki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:04:18