ReflectionTestUtils如何在下面的代码中工作

问题描述

@Service
public class EmailService {

    private JavaMailSenderImpl mailSender;
    
    @postconstruct 
    protected void init() {
        mailSender= new JavaMailSenderImpl();
        mailSender.setHost("some.server.com");
        mailSender.setPort("25");
         
        Properties props = mailSender.getJavaMailProperties();
        props.put("mail.transport.protocol","smtp");
    }
    
    public void sendEmail(String recipient,String subject,String message){   
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage(); 
        simpleMailMessage.setFrom("[email protected]");
        simpleMailMessage.setTo(recipient); 
        simpleMailMessage.setSubject(subject); 
        simpleMailMessage.setText(message);
        mailSender.send(simpleMailMessage);        
    }
}

以上代码是发送电子邮件

public class EmailServiceTest {
    
    @Rule
    public ExpectedException exception = ExpectedException.none();
    
    @InjectMocks
    private EmailService emailService;
    
    @Mock
    private JavaMailSenderImpl mailSender;
    
    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);  
    }
    
    @Test
      public void testemail(){
        exception.expect(MailSendException.class);

        ReflectionTestUtils.setField(emailService,"mailSender",mailSender);
        emailService.sendEmail("me.com","test","this is a unit test");
        
      }
}

我写了一个测试用例,我希望邮件发送失败,但是我没有收到任何错误 在EmailServicetest testemail()中,由于服务器不存在,我期望有MailSendException。谁能告诉我原因是什么?

解决方法

ReflectionTestUtils.setField用您的模拟替换emailService中的mailSender字段。

由于没有为mailSender指定行为,因此此模拟程序上的每个方法调用均以默认行为响应-返回返回类型的默认值。对于void方法,方法调用无效。这就是为什么您没有例外的原因。

您需要使用Mockito.when

指定预期的行为

最重要的是:

通过JavaMailSenderImpl.mailSender构造函数而不是@Autowired方法设置@PostConstruct。这样,您就可以外部化邮件服务器配置并简化测试(例如,无需反射)