Java mockito 单元测试中的 NullPointerException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19863499/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 20:48:50  来源:igfitidea点击:

NullPointerException in mockito unit test

javanullpointerexceptionmockito

提问by Awesome_girl

Here is my SendEmailclass that I am trying to unit test. I am getting a NullPointerException on the line shown below, but I don't know why.

这是我SendEmail正在尝试进行单元测试的班级。我在下面显示的行上收到 NullPointerException,但我不知道为什么。

Also, am I organizing the code properly? I don't exactly know if I am using mockito correctly.

另外,我是否正确组织了代码?我不完全知道我是否正确使用了 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();
    }
}

Here is the class under test:

这是被测类:

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();
    }
}

采纳答案by andyb

I think you are a bit confused on what you need to be testing and mocking. Mockito offers different ways to create mock object, for example: @Mockor Mockito.mock(). There are also different ways to injectthose mock objects into the class under testin order to unit test methods on that class.

我认为您对需要测试和模拟的内容有些困惑。Mockito 提供了不同的方式来创建模拟对象,例如:@MockMockito.mock(). 还有不同的方法可以这些模拟对象注入到被测类中,以便对该类的方法进行单元测试。

Without all the details of the exception or other classes, this will not be a complete answer, but I hope it helps clear up some of the concepts.

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

Note: the following might not compile, but hopefully you'll get the idea.

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

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 = "[email protected]";
    private static final Collection<String> RECIPIENTS = Arrays.asList("[email protected]")
    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)
    }
}