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

JUnit测试无法@Autowired注入Service类但Controller中注入正常如何解决?

问题根本原因

@DataJpaTest 是Spring Boot提供的切片测试注解,默认仅加载JPA相关组件(Repository、EntityManager等),不会扫描并注册@Service注解的业务层Bean,因此测试类中无法注入UserService实例。而你启动完整Web应用时会扫描全量组件,所以Controller层注入可以正常生效。

可行解决方案

  • 方案1:添加@Import注解手动导入UserService
    直接在测试类上新增@Import(UserService.class),手动将UserService注册到测试上下文。同时你需要注意UserService依赖的PasswordEncoder也需要在测试上下文中存在,否则会报新的找不到Bean错误,可以在测试类中额外声明一个PasswordEncoder的测试Bean:
    示例修改后的测试类代码:
    package com.crmbackend.user;
    import static org.assertj.core.api.Assertions.assertThat; 
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.TestConfiguration;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Import;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import com.crmbackend.entity.Role;
    import com.crmbackend.entity.User;
    import com.crmbackend.userService.UserService;
    
    @DataJpaTest(showSql = true)
    @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
    @Rollback(false)
    @Import(UserService.class) // 手动导入UserService
    public class UserServiceTests {
    
        // 测试类内部声明测试用PasswordEncoder
        @TestConfiguration
        static class TestConfig {
            @Bean
            PasswordEncoder passwordEncoder() {
                return new BCryptPasswordEncoder();
            }
        }
    
        @Autowired
        private TestEntityManager entityManager;
        @Autowired
        private UserService service;
    
        @Test
        public void testCreateNewUserWithSingleRolePasswordEncode() {
            Role roleUser = entityManager.find(Role.class, 3);
            User userLucas = new User("lucas9324", "Lucas", "Tom", "qqq542417349", "Lucas9324@outlook.com", "7364832234");
            userLucas.addRole(roleUser);
    
            User savedUser = service.save(userLucas);
            assertThat(savedUser.getId()).isGreaterThan(0);
        }
    }
    
  • 方案2:改用@SpringBootTest注解加载全量上下文
    如果需要加载完整的Spring应用上下文进行集成测试,把@DataJpaTest替换为@SpringBootTest即可,该注解会扫描所有标注了Spring组件注解的类,和你启动正式应用的上下文一致,无需额外导入Bean。缺点是测试启动速度会比切片测试慢。
    示例修改后的测试类注解部分:
    @SpringBootTest
    @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
    @Rollback(false)
    public class UserServiceTests {
        // 原有测试代码保持不变
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 08:09:04