2017-11-18 186 views
1

我有这样的REST控制器:弹簧单元测试结果NoSuchBeanDefinitionException:类没有合格豆 'org.springframework.mail.javamail.JavaMailSender'

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的实现?

+0

您可以发布具有提到 –

回答

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; 
... 
+0

这种依赖的POM文件的部分只是为了补充一点,我重写'doSend'和'connectTransport'也允许使用伪造的邮件服务器。 –