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

Spring Boot单元测试中@Autowired注入属性为空抛空指针异常如何解决

问题原因
  1. 你在测试类的setUp方法中是手动new BuilderServiceImpl(builderRepository,adminUserRepository)创建的服务实例,并非由Spring IoC容器托管。@Autowired注解的字段注入逻辑只有Spring容器创建的对象才会触发,手动new的对象不会自动完成字段注入,因此autoMapper属性默认是null。
  2. 你虽然给测试类加了@SpringBootTest注解,但并未实际使用容器注入的BuilderServiceImpl实例,注解没有起到对应的作用。
解决方案

方案1:改用Spring官方推荐的构造器注入(推荐)

Spring 4.3+之后,类中只有一个构造器的情况下,依赖会自动注入,不需要加@Autowired注解。你已经用了Lombok的@RequiredArgsConstructor,只需要把autoMapper改成final成员即可,调整后的BuilderServiceImpl代码:

@Service
@RequiredArgsConstructor
@Slf4j
public class BuilderServiceImpl implements BuilderService{
    // 改为final成员,不需要@Autowired,@RequiredArgsConstructor会自动生成带该参数的构造器
    private final AutoMapper autoMapper;
    private final BuilderRepository builderRepository;
    private final AdminUserRepository adminUserRepository;

    @Override
    public BuilderDto getByEmail(String email){
    }

    @Override
    public List<BuilderMinDto> getAll() {}

    @Override
    public List<BuilderMinDto> getAll(int page, int size) {}

    @Override
    public SaveBuilderResponse create(Builder builder){
        var str = autoMapper.getDummyText();
        Builder savedBuilder = builderRepository.save(builder);
        return new SaveBuilderResponse(savedBuilder);
    }
}

调整测试类的setUp方法,传入AutoMapper实例即可,你可以根据测试需要选择传入真实实例或者Mock实例:

@BeforeEach
void setUp(){
    autoCloseable = MockitoAnnotations.openMocks(this);
    // 新增AutoMapper实例,也可以用@Mock创建模拟实例满足特殊测试需求
    AutoMapper autoMapper = new AutoMapper();
    underTest = new BuilderServiceImpl(autoMapper, builderRepository, adminUserRepository);
}

方案2:直接使用@SpringBootTest的容器注入能力,用@MockBean替换依赖

不需要手动创建服务实例,直接从容器中注入待测试的服务,用@MockBean替换掉不需要真实调用的Repository依赖,适合需要完整Spring上下文的集成测试场景:

@SpringBootTest
@Slf4j
class BuilderServiceImplTest {
    // 用@MockBean替换容器中的Repository实现
    @MockBean
    private BuilderRepository builderRepository; 
    @MockBean
    private AdminUserRepository adminUserRepository; 

    // 直接注入容器托管的待测试服务,AutoMapper会自动完成注入
    @Autowired
    private BuilderService underTest;

    @Test
    void getByEmail(){}

    @Test
    @Disabled
    void getAll() { }

    @Test
    @Disabled
    void testGetAll() {}

    @Test
    void create() {
        //given
        Builder builder = new Builder();
        builder.setName("John Johnson");
        builder.setCompanyName("Builders Test");
        builder.setEmail("test@builders.com");

        //when
        underTest.create(builder);

        //then
        ArgumentCaptor<Builder> builderArgumentCaptor = ArgumentCaptor.forClass(Builder.class);
        verify(builderRepository).save(builderArgumentCaptor.capture());
        assertThat(builderArgumentCaptor.getValue()).isEqualTo(builder);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 16:15:03