Spring单元测试结果出现NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.mail.javamail.JavaMailSender'。

4

我有一个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 的单元测试(基于教程):

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文件的部分内容,其中提到了这个依赖项? - Lalit Mehra
1个回答

7
JavaMailSender bean未被创建,因为Spring测试运行程序无法获取所需的配置信息。例如,在application.properties中没有spring.mail.host

其中一种解决方法是添加一个TestConfiguration用于JavaMailSender
@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 方法,以便使用虚假邮件服务器。 - y.luis.rojo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接