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

时间:2014-08-04 14:16:52

标签: java junit mockito powermock

我有一个课我需要用mockito测试。 以下是课程和Mockito考试。

dbBuilder.parse(file)总是返回null,因为它调用了几个类,而这些类又调用了jar文件中的几个方法。即使我嘲笑了所有这些,它总是返回null。我无法跟踪空值的来源。我试图压制这些方法,但仍无用。

由于此方法调用返回null,因此doc值为null。因此,文档调用getElementsByTagName方法,并且使用NullPointerException运行mockito测试失败。在我需要测试此方法的代码后面有几行代码。

如何解决此问题?

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

2 个答案:

答案 0 :(得分:1)

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

在我看来,您需要模拟DocumentBuilder类的构造函数调用。执行此操作时,需要在PrepareForTest注释中包含调用构造函数类,因此请确保DocumentClass存在于此处。在模拟构造函数调用时,请参阅documentation(主要是快速摘要)以了解准备测试的内容。

然后,您还需要在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();
    }
}

答案 1 :(得分:0)

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