我正在尝试模拟一个org.w3c.dom.Document对象,这样调用XPath.evaluate()应该返回一个定义的值,例如foo,如下所示:
Document doc = Mockito.mock(Document.class);
Mockito.when(XPathUtils.xpath.evaluate("/MyNode/text()", doc, XPathConstants.STRING)).thenReturn("foo");
我将doc对象传递给目标方法,该方法将节点 MyNode 的文本内容提取为 foo 。
我尝试过模拟节点并在doc对象中设置如下:
Node nodeMock = mock(Node.class);
NodeList list = Mockito.mock(NodeList.class);
Element element = Mockito.mock(Element.class);
Mockito.when(list.getLength()).thenReturn(1);
Mockito.when(list.item(0)).thenReturn(nodeMock);
Mockito.when(doc.getNodeType()).thenReturn(Node.DOCUMENT_NODE);
Mockito.when(element.getNodeType()).thenReturn(Node.ELEMENT_NODE);
Mockito.when(nodeMock.getNodeType()).thenReturn(Node.TEXT_NODE);
Mockito.when(doc.hasChildNodes()).thenReturn(false);
Mockito.when(element.hasChildNodes()).thenReturn(true);
Mockito.when(nodeMock.hasChildNodes()).thenReturn(false);
Mockito.when(nodeMock.getNodeName()).thenReturn("MyNode");
Mockito.when(nodeMock.getTextContent()).thenReturn("MyValue");
Mockito.when(element.getChildNodes()).thenReturn(list);
Mockito.when(doc.getDocumentElement()).thenReturn(element);
但这会产生如下错误:
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:String不能 由hasChildNodes()返回hasChildNodes()应返回boolean
我的方法是否正确,我只是缺少另一个模拟,或者我应该采用不同的方法?请帮忙。
答案 0 :(得分:3)
Don't mock types you don't own !,这是错误的。
为了避免重复,这里的答案解释了为什么https://stackoverflow.com/a/28698223/48136
编辑:我的意思是代码应该有可用的构建器方法(在生产或测试类路径中)应该能够创建<强>真实 Document
无论该文档的来源是什么,但肯定不是模拟。
例如,这个工厂方法或构建器可以这样使用DocumentBuilder
:
class FakeXMLBuilder {
static Document fromString(String xml) {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
return dBuilder.parse(new ByteArrayInputStream(xml.getBytes("UTF_8")));
}
}
当然,这必须根据项目的需要量身定制,这可以进行更多定制。在我目前的项目中,我们有很多可以创建对象,json等的测试构建器。例如:
Leg leg = legWithRandomId().contact("Bob").duration(234, SECONDS).build();
String leg = legWithRandomId().contact("Bob").duration(234, SECONDS).toJSON();
String leg = legWithRandomId().contact("Bob").duration(234, SECONDS).toXML();
Whatever leg = legWithRandomId().contact("Bob").duration(234, SECONDS).to(WhateverFactory.whateverFactory());
答案 1 :(得分:0)
将Jsoup.parse()
与测试XML字符串一起使用。像下面这样的东西应该可以工作,用于测试我假设为testClassInstance.readFromConnection(String url)
的某些实例方法:
// Turn a block of XML (static String or one read from a file) into a Document
Document document = Jsoup.parse(articleXml);
// Tell Mockito what to do with the Document
Mockito.when(testClassInstance.readFromConnection(Mockito.any()))
.thenReturn(document);
我习惯将其称为“模拟”文档,但是它只是创建并使用一个真实的文档,然后将其用于模拟其他方法。您可以根据自己的喜好构建document
的xml版本,也可以使用其常规的setter对其进行操作,以测试代码对文件的作用。您还可以用一个常量字符串来代替读取文件的麻烦,只要它足够短以至于易于管理。