【问题标题】:Springboot test failed to load ApplicationContext in Junit 5Springboot 测试无法在 Junit 5 中加载 ApplicationContext
【发布时间】:2026-02-21 16:35:01
【问题描述】:

我正在尝试使用 Junit5 为特定服务类创建单元/集成测试,以避免整个项目过载。

所以在这里我尝试运行 EmailService 及其依赖类,但我得到了 java.lang.IllegalStateException: Failed to load ApplicationContext. Error creating bean with name 'emailSenderService. No qualifying bean of type 'org.springframework.mail.javamail.JavaMailSender' available: expected at least 1 bean which qualifies as autowire candidate.'

我是否必须运行整个应用程序才能测试单个服务?

build.yml

{
    testImplementation ('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'junit', module: 'junit'
    }
    testImplementation "org.junit.jupiter:junit-jupiter:5.4.1"
}

服务:

public class EmailSenderService {
    private final JavaMailSender sender;
    private final SpringTemplateEngine templateEngine;
    private final MessageSource i18n;
    public EmailSenderService(JavaMailSender sender, SpringTemplateEngine templateEngine,
                              @Qualifier("messageSource") MessageSource i18n) {
        this.sender = sender;
        this.templateEngine = templateEngine;
        this.i18n = i18n;
    }
}

测试类:

@SpringBootTest(
        classes = {EmailSenderService.class}
)
@ExtendWith({SpringExtension.class})
class EmailServiceTest {

    private static GreenMail smtp;

    @Autowired
    private EmailSenderService mailService;

    @BeforeAll
    static void init() {
        smtp = new GreenMail(new ServerSetup(3026,null,"smtp"));
        smtp.start();
    }

    @AfterAll
    static void tearDown() {
        smtp.stop();
    }

    @BeforeEach
    void clearUp() throws FolderException {
        smtp.purgeEmailFromAllMailboxes();
    }

    @Test
    void testNewBidRequestEmail() throws MessagingException {
        EmailMessageTemplateDto contact = new EmailMessageTemplateDto("test","test@test.com","test message");
        mailService.sendUserContactEmail(contact);
        Assertions.assertTrue(smtp.waitForIncomingEmail(1));
    }
}

错误:

2019-04-03 14:56:06.146 WARN 732 --- [主要] o.s.w.c.s.GenericWebApplicationContext:遇到异常 在上下文初始化期间 - 取消刷新尝试: org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为“emailSenderService”的 bean 时出错:不满意 通过构造函数参数 0 表示的依赖关系;嵌套异常 是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 否 符合条件的 bean 类型 'org.springframework.mail.javamail.JavaMailSender' 可用:预期 至少 1 个符合自动装配候选资格的 bean。依赖 注释:{} 2019-04-03 14:56:06.153 错误 732 --- [
主要] o.s.b.d.LoggingFailureAnalysisReporter:

***************************应用程序启动失败


说明:

构造函数的参数0 com.server.server.service.EmailSenderService 需要一个 bean 输入 'org.springframework.mail.javamail.JavaMailSender' 不能 找到了。

行动:

考虑定义一个 bean 类型 'org.springframework.mail.javamail.JavaMailSender' 在你的 配置。

2019-04-03 14:56:06.159 错误 732 --- [主要] o.s.test.context.TestContextManager : 捕获异常同时 允许 TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@342c38f8] 准备测试实例 [com.server.server.test.junit.EmailServiceTest@4c7a078]

java.lang.IllegalStateException: 无法加载 ApplicationContext 在 org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125) ~[spring-test-5.1.5.RELEASE.jar:5.1.5.RELEASE] 在 org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108) ...

【问题讨论】:

    标签: java spring-boot junit5


    【解决方案1】:

    问题在于您确实没有可用的JavaMailSender(而且您在测试期间不想要真正的JavaMailSender)。您有四个选择:

    • 在测试配置中注册一个模拟/存根JavaMailSender bean。

    • 1234563
    • 在这种情况下,由于您实际上是在尝试测试 EmailSenderService 本身,请在您的 application-test 属性(或注释)中设置 spring.mail.host: localhost

    • 这里根本不要使用 Spring DI。构造函数注入的主要优点是您可以手动实例化您的 bean,并且您可以 new 升级您的 EmailSenderService 及其依赖项。

    如果我了解您的测试预期范围,那么#3 可能是适合您的解决方案。

    【讨论】:

    • 第一个选项:如果我使用模拟 JavaMailSender,它可以发送电子邮件吗?对于第二个选项,在我提出一些问题之前,我将尝试了解有关 @ConditionalOnBean 注释的更多信息。关于第三个选项,在我提交这个问题之前,我已经有一个默认的application.yml 文件和spring.mail.host: localhost。第四个选项,我需要检索主spring应用程序的任何参数来创建new EmailSenderService吗?
    • @LunaticJape 如果你这样做,它不会发送真正的邮件,这就是为什么它可能不是你想要在这里测试的最佳选择。在第三个选项中,您应该得到一个JavaMailSender;确保您已包含spring-boot-starter-mail,如果仍然无法正常工作,请使用--debug 获取自动配置报告并发布。对于选项 4,这取决于您要测试的内容;您根本不需要 Spring,但测试您的消息和模板引擎在 Spring 上下文中是否正确配置会很有用。