当试图使用Mockito来测试发送电子邮件时,我在函数中创建了一个multipartemail对象,但是测试失败了,为什么呢?

时间:2013-11-19 15:09:32

标签: unit-testing mockito

这是我的单元测试代码。

 public class StatsTest extends AbstractTestCase {
@Mock 
//EmailInfo mockMetricsEmail = Mockito.mock(EmailInfo.class);
//EmailSenderImpl mockEmailSenderImpl = Mockito.mock(EmailSenderImpl.class);
private MultiPartEmail mockMultiPartEmail = Mockito.mock(HtmlEmail.class); 

private static final String testEmailBody = "This is the test email body.";
private static final String testSender = "seemakur@amazon.com"; 
private static final String testRecipient = ("seemakur@amazon.com");
private static final String testEmailSubject = "subject";
private static final String testHostName = "seemakur.desktop.amazon.com";
private static final MultiPartEmail testHtmlEmail = new HtmlEmail();

EmailSenderImpl emailSenderImplObj = new EmailSenderImpl();
EmailInfo emailInfoObj = new EmailInfo(testEmailBody, testSender, testRecipient, testEmailSubject, testHostName, testHtmlEmail);



@Before
public void setUp() throws Throwable {
    super.setUp();
    MockitoAnnotations.initMocks(this); // will instantiate "mockMultiPartEmail"
    // instantiate our class under test
}

@Test(expected = EmailException.class)
public void testSendEmail() throws EmailException, IOException {

    MultiPartEmail testMultiPartEmail = Mockito.spy(new HtmlEmail());
    Mockito.doReturn(mockMultiPartEmail).when(emailInfoObj).getMultiPartEmail(); //stub(spy.getMultiPartEmail()).toReturn(mockMultiPartEmail);
    Mockito.when(mockMultiPartEmail.send()).thenThrow(new EmailException("Failed on multipartEmail.send(), hence could not send the email."));

    // when the method under test is called
    try {
        //testEmailSenderImplObj.sendHtmlTableAsEmail(testMetricsEmail);
        emailSenderImplObj.sendHtmlTableAsEmail(emailInfoObj); //inject mock & invoke what to test  
        fail("Expecting EmailException");
    }catch(EmailException e){
        e.printStackTrace();
    }

    Mockito.verify(mockMultiPartEmail).send();Mockito.doReturn(mockMultiPartEmail).when(emailInfoObj).getMultiPartEmail(); //stub(spy.getMultiPartEmail()).toReturn(mockMultiPartEmail);

}

   }

我有三个与此电子邮件功能相关的课程: 首先是下面的emailInfo数据对象

   @Data
   public class EmailInfo {
private String emailBody;
private String senderEmail;
private String receiversEmails;
private String emailSubject;
private String hostName;
    private MultiPartEmail multiPartEmail;

public EmailInfo(String emailBody, String senderEmail, String receiversEmails, String emailSubject, String hostName, MultiPartEmail multiPartEmail) {

    this.setEmailBody(emailBody);
    this.setSenderEmail(senderEmail);
    this.setReceiversEmails(receiversEmails);
    this.setEmailSubject(emailSubject);
    this.setHostName(hostName);
    this.setMultiPartEmail(multiPartEmail);
}

public String getSenderEmail() {
    return senderEmail;
}
public void setSenderEmail(String senderEmail) {
    this.senderEmail = senderEmail;
}

public String getEmailBody() {
    return emailBody;
}
public void setEmailBody(String emailBody) {
    this.emailBody = emailBody;
}


public String getReceiversEmails() {
    return receiversEmails;
}
public void setReceiversEmails(String receiversEmails2) {
    this.receiversEmails = receiversEmails2;
}


public String getEmailSubject() {
    return emailSubject;
}
public void setEmailSubject(String emailSubject) {
    this.emailSubject = emailSubject;
}


public String getHostName() {
    return hostName;
}
public void setHostName(String hostName) {
    this.hostName = hostName;
}

public MultiPartEmail getMultiPartEmail() {
    return multiPartEmail;
}

public void setMultiPartEmail(MultiPartEmail multiPartEmail) {
    this.multiPartEmail = multiPartEmail;
}

    }

第二课:EmailSenderImpl.java

     public class EmailSenderImpl implements EmailSender{

     // public MultiPartEmail getEmail(){
     //     return multiPartEmail;
     // }
     // 
     // public void setEmail(MultiPartEmail multiPartEmail){
     //     this.multiPartEmail = multiPartEmail;
     // }

    public void sendHtmlTableAsEmail(EmailInfo emailInfo)throws IOException, EmailException{
    MultiPartEmail multiPartEmail = new HtmlEmail();
    multiPartEmail.setHostName(emailInfo.getHostName());
    multiPartEmail.addTo(emailInfo.getReceiversEmails());
    multiPartEmail.setFrom(emailInfo.getSenderEmail());
    multiPartEmail.setSubject(emailInfo.getEmailSubject());
    multiPartEmail.setMsg((emailInfo.getEmailBody()).toString());
    multiPartEmail.send();
}

}

最后是EMailSender.java接口。

     public interface EmailSender{
public abstract void sendHtmlTableAsEmail(EmailInfo emailInfo)throws IOException, EmailException;
     }

我认为我有一个简单函数的类很多,因为我不能使用静态方法,我必须将“业务逻辑”与“函数逻辑”分开。我需要有接口,这是必要的。如果有更好的方法来组织这个,请告诉我。

现在,当我运行单元测试时,它就失败了:“Mockito.doReturn(mockMultiPartEmail).when(emailInfoObj).getMultiPartEmail(); //stub(spy.getMultiPartEmail()).toReturn(mockMultiPartEmail);         “);”

错误读取:org.mockito.exceptions.misusing.NotAMockException

1 个答案:

答案 0 :(得分:0)

在您的原始代码中,问题在于此行

Mockito.doReturn(mockMultiPartEmail).when(emailInfoObj).getMultiPartEmail();

您正在尝试使用此行存根创建的行为

EmailInfo emailInfoObj = new EmailInfo(testEmailBody, testSender, testRecipient, testEmailSubject, testHostName, testHtmlEmail);

但这不是模拟或间谍。 Mockito只允许你存储模拟和间谍的行为,而不仅仅是任意对象。

我不知道在后续更新后你是否还有这个问题,因为无法读取嵌入评论中的代码。