Mockito模拟对象从方法内部的方法调用中分配了空值 [英] Mockito mocked object is assigned a null value from method calls inside a method
问题描述
我有一个需要通过模拟测试的类. 下面是该类和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屋!