Mockito模拟对象从方法内部的方法调用中分配了空值 [英] Mockito mocked object is assigned a null value from method calls inside a method

查看:209
本文介绍了Mockito模拟对象从方法内部的方法调用中分配了空值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要通过模拟测试的类. 下面是该类和Mockito测试.

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

dbBuilder.parse(file)始终返回null,因为它调用了几个类,这些类又调用了jar文件中的多个方法.即使我嘲笑了所有这些,但它始终返回null.我无法跟踪空值从何而来.我试图抑制这些方法,但仍然没有用.

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.

由于此方法调用返回null,因此doc值为null.因此,文档调用了getElementsByTagName方法,并且运行的模仿测试失败.在此方法之后,我需要测试几行代码.

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.

如何解决此问题?

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,但是我将提供更详细的答案以便检查工作所需的所有详细信息.

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.

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

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.

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

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

此外,我认为您不需要调用Document类的构造函数,在将引用简单地替换为dbBuilder中的引用之前,您无需对其进行任何操作.

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

这篇关于Mockito模拟对象从方法内部的方法调用中分配了空值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆