Mockito mocked object is assigned a null value from method calls inside a method

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-23 06:25:06

问题


I have a class that I need to test with mockito. Below is the class and the Mockito Test.

dbBuilder.parse(file) always returns null because it calls several classes which, in turn, call several methods in a jar file. Even though I mocked all of them it always returns null. I couldn't track where the null value is coming from. I tried to suppress the methods but still no use.

Since this method call returns null, the doc value is null. So the doc calls the getElementsByTagName method and running the mockito tests fails with NullPointerException. There are several lines of code after this code in this method i need to test.

How do I resolve this issue?

class DocumentClass{
    public void docMethod(){
        DocumentBuilder dbBuilder = new DocumentBuilder();
        Document doc = new Document();
        FileStream file = new FileStream(new File(some path));
        doc = dbBuilder.parse(file);
        NodeList nodes = doc.getElementsByTagName("documents");
    }
}

@RunWith(PowerMockRunner.class) 
@PrepareForTest({Document.class,DocumentBuilder.class,FileStream.class})
public class TestDocument{
    @Test
    public documentTest(){
        DocumentBuilder dbBuilder = PowerMockito.mock(DocumentBuilder.class);
        Document doc = PowerMockito.mock(Document.class);
        FileStream file = PowerMockito.mock(FileStream.class);
        PowerMockito.whenNew(FileStream.class).withAnyArguments().thenReturn(file);
        PowerMockito.doReturn(doc).when(dbBuilder).parse(file);
        DocumentClass docClass = PowerMockito.mock(DocumentClass.class);
        docClass.docMethod();
   }
}

回答1:


Edit: I realise you've mentioned that you've tried the whenNew before, but I'm providing the answer in a bit more detail so as to check all of the details required for this to work.

It looks to me like you'll need to mock the constructor call for the DocumentBuilder class. When you do this, you need to include the class that calls the constructor in the PrepareForTest annotation, so make sure that DocumentClass exists there. See the documentation(primarily the quick summary) for what to prepare for test when mocking constructor calls.

Then, you'll also need to provide an expectation call for the method call on the DocumentBuilder.

Also, I don't think you need to call the constructor for the Document class, you're not doing anything with it before you simply replace the reference with the one from the dbBuilder.

So I think your method can look like this:

class DocumentClass{
    public void docMethod(){
        final FileStream file = new FileStream(new File(some path));

        final DocumentBuilder dbBuilder = new DocumentBuilder();
        final Document doc = dbBuilder.parse(file);

        final NodeList nodes = doc.getElementsByTagName("documents");
    }
}

So I think your test wants to look something like this: (I have not tried this code, so I apologise for any typos)

@RunWith(PowerMockRunner.class)
@PrepareForTest({DocumentClass.class, Document.class, DocumentBuilder.class, FileStream.class})
public class TestDocument {
    @Test
    public documentTest() {
        final DocumentBuilder dbBuilder = PowerMockito.mock(DocumentBuilder.class);
        final Document doc = PowerMockito.mock(Document.class);
        final FileStream file = PowerMockito.mock(FileStream.class);
        final NodeList nodes = PowerMockito.mock(NodeList.class);

        PowerMockito.whenNew(FileStream.class).withAnyArguments().thenReturn(file);
        PowerMockito.whenNew(DocumentBuilder).thenReturn(dbBuilder);
        PowerMockito.doReturn(doc).when(dbBuilder).parse(file);
        PowerMockito.doReturn(node).when(doc).getElementsByTagName("documents");

        PowerMock.replayAll();

        DocumentClass docClass = new DocumentClass();
        docClass.docMethod();

        PowerMock.verifyAll();
    }
}



回答2:


You didn't use PowerMockito.whenNew(DocumentBuilder.class) so the builder in use is a real builder, not a mock.



来源:https://stackoverflow.com/questions/25120820/mockito-mocked-object-is-assigned-a-null-value-from-method-calls-inside-a-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!