模拟对象从方法内部的方法调用中被分配一个空值



我有一个类,我需要用mockito测试。下面是类和Mockito测试。

dbBuilder.parse(file)总是返回null,因为它调用了几个类,而这些类又调用了jar文件中的几个方法。尽管我对它们都进行了模拟,但它总是返回null。我无法追踪空值的来源。我试图压制这些方法,但仍然无济于事。

由于此方法调用返回null,因此doc值为null。因此,文档调用getElementsByTagName方法,运行NullPointerException模拟测试失败。在这个方法的代码之后,我需要测试几行代码。

我如何解决这个问题?

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

编辑:我意识到你已经提到你之前已经尝试过whenNew,但我提供了更详细的答案,以便检查工作所需的所有细节。

在我看来,你需要模拟DocumentBuilder类的构造函数调用。这样做时,需要在PrepareForTest注释中包含调用构造函数的类,因此要确保那里存在DocumentClass。请参阅文档(主要是快速摘要),了解在模拟构造函数调用时为测试准备的内容。

然后,您还需要为DocumentBuilder上的方法调用提供一个期望调用。

另外,我认为您不需要调用Document类的构造函数,在您简单地将引用替换为dbBuilder中的引用之前,您没有使用它做任何事情。

所以我认为你的方法可以是这样的:

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

所以我认为你的测试想要看起来像这样:(我没有尝试过这个代码,所以我为任何打字错误道歉)

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

您没有使用PowerMockito.whenNew(DocumentBuilder.class),因此使用的构建器是真正的构建器,而不是模拟的。

最新更新