【问题标题】:Spring unit test results in NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.mail.javamail.JavaMailSender'Spring 单元测试导致 NoSuchBeanDefinitionException:没有“org.springframework.mail.javamail.JavaMailSender”类型的合格 bean
【发布时间】:2018-05-01 20:59:24
【问题描述】:

我有这个 REST 控制器:

package com.company.rest;

@RestController
@RequestMapping("/v1/orders")
public class OrderController {

    @Autowired
    private OrderService orderService;
...

作为OrderService 实现:

package com.company.service.impl;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private MessageService messageService;
...

MessageService 实现:

package com.company.service.impl;

import org.springframework.mail.javamail.JavaMailSender;

@Service
public class MessageServiceImpl implements MessageService {

    @Autowired
    public JavaMailSender emailSender;
...

这在开发环境中完美运行,但我对OrderController 进行了这个单元测试(基于this 教程):

package com.company.test;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = AdminApplication.class)
@WebAppConfiguration
public class OrderTest {

    private MockMvc mockMvc;

    @Autowired
    private OrderService orderService;
...

导致:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.mail.javamail.JavaMailSender' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

为什么这种依赖在生产中得到满足,但在测试中却没有?我需要做什么才能让这个单元测试成功地注入(或模拟)JavaMailSender 实现?

【问题讨论】:

  • 你能把pom文件中提到这个依赖的部分贴出来

标签: java spring unit-testing spring-boot junit


【解决方案1】:

JavaMailSender bean 未创建,因为 Spring 测试运行器无法获得所需的配置。 比如application.properties中没有spring.mail.host

其中一个解决方案是为JavaMailSender 添加TestConfiguration

@TestConfiguration
public class TestConfigForMail {

  @Bean
  public JavaMailSender mailSender() {
    final JavaMailSenderImpl sender = new MockMailSender();
    return sender;
  }

  private class MockMailSender extends JavaMailSenderImpl {
    @Override
    public void send(final MimeMessagePreparator mimeMessagePreparator) throws MailException {
      final MimeMessage mimeMessage = createMimeMessage();
      try {
        mimeMessagePreparator.prepare(mimeMessage);
        final String content = (String) mimeMessage.getContent();
        final Properties javaMailProperties = getJavaMailProperties();
        javaMailProperties.setProperty("mailContent", content);
      } catch (final Exception e) {
        throw new MailPreparationException(e);
      }
    }
  }
}

注意:MockMailSender 的代码来自Fahd Shariff

然后将TestConfiguration 导入您的测试用例。

@RunWith(SpringRunner.class)
@SpringBootTest(classes = AdminApplication.class)
@Import(TestConfigForMail.class)
@WebAppConfiguration
public class OrderTest {

    private MockMvc mockMvc;

    @Autowired
    private OrderService orderService;
...

【讨论】:

  • 只是补充一点,我覆盖了doSendconnectTransport 也允许使用假邮件服务器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-18
  • 2020-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-04
  • 2023-03-22
相关资源
最近更新 更多