Java mockito单元测试中的NullPointerException

Java mockito单元测试中的NullPointerException,java,nullpointerexception,mockito,Java,Nullpointerexception,Mockito,这是我的sendmail类,我正在尝试对其进行单元测试。我在下面显示的行中得到一个NullPointerException,但我不知道为什么 另外,我是否正确地组织了代码?我不知道我是否正确使用mockito public class StatsTest extends AbstractTestCase { @Mock MultiPartEmail MultiPartEmailMock; StatsTest statsTestObj; SendEmail mock

这是我的
sendmail
类,我正在尝试对其进行单元测试。我在下面显示的行中得到一个NullPointerException,但我不知道为什么

另外,我是否正确地组织了代码?我不知道我是否正确使用mockito

public class StatsTest extends AbstractTestCase {
    @Mock
    MultiPartEmail MultiPartEmailMock;
    StatsTest statsTestObj;
    SendEmail mockedEmail;

    @Before
    public void setUp() throws Throwable {
        super.setUp();
        MockitoAnnotations.initMocks(this);
    }

    @Test(expected = ValidationException.class)
    public void testSendEmail() throws EmailException, IOException {
        MultiPartEmail multiPartEmailMock;
        SendEmail mockedEmail = Mockito.mock(SendEmail.class);
        Mockito.when((mockedEmail.getHtmlEmail()).send()) 
            .thenThrow(new ValidationException("Could not send the Email."));

        ^^ the line above is where the null pointer error is

        mockedEmail.sendEmail();
    }
}
下面是正在测试的类:

public class SendEmail {
    private StringBuilder emailBody;
    private String senderEmail;
    private ArrayList<String> receiversEmails;
    private String emailSubject;
    private String hostName;
    private MultiPartEmail htmlEmail;

    public SendEmail(StringBuilder emailBody, String senderEmail, ArrayList<String> 
        receiversEmails, String emailSubject, String hostName, MultiPartEmail htmlEmail) {
        this.setEmailBody(emailBody);
        this.setSenderEmail(senderEmail);
        this.setReceiversEmails(receiversEmails);
        this.setEmailSubject(emailSubject);
        this.setHostName(hostName);
        this.setHtmlEmail(htmlEmail);
    }

    public void sendEmail()throws IOException, EmailException{

        htmlEmail.setHostName(getHostName());
        htmlEmail.addTo(getReceiversEmails().get(0));
        for(int i=0; i<getReceiversEmails().size(); i++){
            htmlEmail.addCc(getReceiversEmails().get(i));   
        }
        htmlEmail.setFrom(getSenderEmail());
        htmlEmail.setSubject(getEmailSubject());
        htmlEmail.setMsg((getEmailBody()).toString());
        htmlEmail.send();
    }
}
公共类发送电子邮件{
私人机构;
私有字符串senderEmail;
私人ArrayList接收人;
私有字符串主题;
私有字符串主机名;
专用多端口邮件htmlEmail;
公共发送电子邮件(StringBuilder电子邮件正文、字符串发送电子邮件、ArrayList
接收方邮件、字符串emailSubject、字符串主机名、多部分邮件htmlEmail){
this.setEmailBody(emailBody);
此.setSenderEmail(senderEmail);
此.setReceiversMail(ReceiversMail);
this.setEmailSubject(emailSubject);
这个.setHostName(主机名);
这个.setHtmlEmail(htmlEmail);
}
public void sendmail()引发IOException,EmailException{
setHostName(getHostName());
htmlEmail.addTo(getReceiversEmails().get(0));

对于(int i=0;i我认为您对需要测试和模拟的内容有点困惑。Mockito提供了不同的方法来创建模拟对象,例如:
@mock
Mockito.mock()
。也有不同的方法将这些模拟对象注入到被测试的类中,以便对该类上的方法进行单元测试

如果没有异常或其他类的所有细节,这将不是一个完整的答案,但我希望它有助于澄清一些概念

注意:以下内容可能无法编译,但希望您能理解

公共类StatsTest扩展了AbstractTestCase{
@Mock MultiPartEmail mockMultiPartEmail;//此模拟将用于测试类的实例化
SendEmail SendEmail;//重命名,因为这不是模拟,而是测试中的类
//定义一些我们可以断言的东西(可能在其他测试中…)
私有静态最终StringBuilder主体=新StringBuilder(“主体”);
私有静态最终字符串发送器=”sender@foo.com";
私有静态最终集合收件人=数组.asList(“recepient@foo.com")
私有静态最终字符串SUBJECT=“SUBJECT”;
私有静态最终字符串HOSTNAME=“HOSTNAME”;
@以前
public void setUp()抛出可丢弃的{
super.setUp();
initMocks(this);//将实例化“mockMultiPartEmail”
//实例化我们正在测试的类
sendEmail=新的sendEmail(正文、发件人、收件人、主题、主机名、mockMultiPartEmail);
}
@测试(预期=ValidationException.class)
public void testSendEmail()引发EmailException,IOException{
//在一定条件下
Mockito.when(mockMultiPartEmail.send()).thenthow(newvalidationexception(“无法发送电子邮件”);
//当调用被测试的方法时
sendmail.sendmail();
//然后将抛出异常(您在@Test注释中正确地预料到了这一点)
}
}

你能给我一个行号吗?我运行了它,它在以下行停止:Mockito.when(mockMultiPartEmail.send.()。然后抛出(new ValidationException(“无法发送电子邮件”));异常为:java.lang.exception:意外异常,应为,但如果不查看您的所有代码,我将无能为力!我上面的示例是在不了解您的完整代码库的情况下编写的。错误是mockito期望出现
ValidationException
异常,但实际上得到了其他异常。从这一点来看,可能是由于您的测试抛出了“无法由该特定方法调用抛出”的内容造成的.您的代码是否真的抛出了一个
ValidationException
?从问题中的代码来看,答案是否定的
public class StatsTest extends AbstractTestCase {
    @Mock MultiPartEmail mockMultiPartEmail; // this mock will be used in the instantiaion of the class under test
    SendEmail sendEmail; // renamed as this is not a mock, it is the class under test

    // define some things we can make assertions against (probably in some other tests...)
    private static final StringBuilder BODY = new StringBuilder("body");
    private static final String SENDER = "sender@foo.com";
    private static final Collection<String> RECIPIENTS = Arrays.asList("recepient@foo.com")
    private static final String SUBJECT = "subject";
    private static final String HOSTNAME = "hostname";

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

        // instantiate our class under test
        sendEmail = new SendEmail(BODY, SENDER, RECIPIENTS, SUBJECT, HOSTNAME, mockMultiPartEmail);
    }

    @Test(expected = ValidationException.class)
    public void testSendEmail() throws EmailException, IOException {
        // given some condition
        Mockito.when(mockMultiPartEmail.send()).thenThrow(new ValidationException("Could not send the Email."));

        // when the method under test is called
        sendEmail.sendEmail();

        // then the exception will be thrown (and you have correctly expected this on the @Test annotation)
    }
}