首页 > 解决方案 > Springboot 测试无法在 Junit 5 中加载 ApplicationContext

问题描述

我正在尝试使用 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.'.

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

构建.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 --- [main] oswcsGenericWebApplicationContext:在上下文初始化期间遇到异常 - 取消刷新尝试:org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为“emailSenderService”的 bean 时出错:不满意通过构造函数参数 0 表示的依赖关系;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有“org.springframework.mail.javamail.JavaMailSender”类型的合格 bean 可用:预计至少有 1 个有资格作为自动装配候选者的 bean。依赖注释:{} 2019-04-03 14:56:06.153 ERROR 732 --- [
main] osbdLoggingFailureAnalysisReporter:

****************************** 应用程序无法启动


描述:

com.server.server.service.EmailSenderService 中构造函数的参数 0 需要找不到类型为“org.springframework.mail.javamail.JavaMailSender”的 bean。

行动:

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

2019-04-03 14:56:06.159 错误 732 --- [main] ostest.context.TestContextManager:在允许 TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@342c38f8] 准备测试实例 [com .server.server.test.junit.EmailServiceTest@4c7a078]

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

标签: javaspring-bootjunit5

解决方案


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

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

  • 使用自动配置来创建EmailSenderService自己@ConditionalOnBean(JavaMailSender.class)并注册一个存根(如果没有存根)(这通常是我为测试“系统是否发送事务性邮件?”所做的)。

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

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

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


推荐阅读