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

@SpringBootTest中显式声明JavaMailSender Bean仍自动注入为null如何解决

问题根因与解决方案

1 首要原因:注入时机错误

你在类属性定义阶段直接初始化MailService,此时Spring还未完成@Autowired字段的注入操作,javaMailSender还处于null状态,自然传给MailService的参数也是null。
Spring的字段注入逻辑是在测试类实例化完成之后才执行的,类属性的初始化操作是在实例化过程中执行的,顺序早于注入。

2 次要排查点:配置类未被加载

如果调整时机后还是null,说明你的MailSenderTestConfiguration没有被Spring Boot的测试扫描逻辑识别到,默认@SpringBootTest只会扫描启动类所在包、测试类所在包及其子包下的配置类,路径不匹配就不会创建对应的Bean。

修复步骤

方案一:使用构造注入(推荐)

Spring Boot 4.3+版本支持测试类构造参数自动注入,直接在构造阶段完成MailService初始化即可:

@SpringBootTest(classes = MailSenderTestConfiguration.class) // 显式指定加载配置类,避免扫描问题
class MailServiceTest {
    private final JavaMailSender javaMailSender;
    private final MailService mailService;
    private final GreenMail greenMail = new GreenMail();

    public MailServiceTest(@Qualifier("testJavaMailSender") JavaMailSender javaMailSender) {
        this.javaMailSender = javaMailSender;
        this.mailService = new MailService(javaMailSender);
    }


    @BeforeEach
    public void setup() {
        greenMail.setUser("foo@localhost", "foo", "password");
        greenMail.start();
    }

    @AfterEach
    public void teardown() {
        greenMail.stop();
    }

    @Test
    public void shouldSendNotificationEmailToRecipient() {
        final String expectedText = "An error occured while executing the Jira Connector import sync."
                + "Please see the log file: 'jira-connector.log' in the application directory";

        mailService.notifyAdmin();

        final MimeMessage[] receivedMessage = greenMail.getReceivedMessagesForDomain("my-ag.com");
        final String actual = GreenMailUtil.getBody(receivedMessage[0]);

        assertThat(actual).isEqualTo(expectedText);

    }
}

方案二:调整初始化时机到@BeforeEach

也可以把MailService的初始化放到@BeforeEach方法中,此时Spring已经完成了所有字段注入:

@SpringBootTest(classes = MailSenderTestConfiguration.class)
class MailServiceTest {
    @Autowired
    @Qualifier("testJavaMailSender")
    private JavaMailSender javaMailSender;
    private MailService mailService;
    private final GreenMail greenMail = new GreenMail();


    @BeforeEach
    public void setup() {
        this.mailService = new MailService(javaMailSender);
        greenMail.setUser("foo@localhost", "foo", "password");
        greenMail.start();
    }

    // 其余代码保持不变
}

额外注意点

你当前配置的JavaMailSender指向了真实的Gmail SMTP服务器,测试邮件不会进入GreenMail,会导致后续收不到测试邮件断言失败,需要修改配置类的Bean参数适配GreenMail:

@Configuration
class MailSenderTestConfiguration {

    @Bean(name = "testJavaMailSender")
    public JavaMailSender testJavaMailSender() {
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        // 替换为GreenMail的本地服务配置,默认SMTP端口为3025
        mailSender.setHost("localhost");
        mailSender.setPort(3025);

        mailSender.setUsername("foo@localhost");
        mailSender.setPassword("password");

        Properties props = mailSender.getJavaMailProperties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.debug", "true");

        return mailSender;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 00:45:02