提前致歉-我知道已经被问了一千遍了,但是我浏览了这么多的文章/文档,我实在是太丢脸了。
我有一个接收XML文件的类,然后使用DocumentBuilder将其解析为一个新文件,该文件将用作其他类使用的源。
我需要测试我的方法(无效)。我的项目已经完成,但是我需要测试。
如果有人愿意向我展示如何完成此操作,则可以继续使用其他类,并遵循相同的逻辑,因为项目中90%的方法均不返回任何内容。
谢谢...
public class XmlToCsv {
public static void xmlToCsv(String sourceXlsFile, String sourceCsvFile, String sourceXmlFile) throws Exception {
//define the files
File stylesheet = new File(sourceXlsFile);
File xmlSource = new File(sourceXmlFile);
//create the DocumentBuilder to parse the XML file
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xmlSource);
//input the stylesheet to transform the XML to
StreamSource stylesource = new StreamSource(stylesheet);
Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);
//write a new output file using the stylesheet format
Source source = new DOMSource(document);
Result outputTarget = new StreamResult(new File(sourceCsvFile));
transformer.transform(source, outputTarget);
}
}
您实际上想做的不是做到这一点的方法。你应该只测试XmlToCsv
类,而不是由这个类使用的类(DocumentBuilderFactory
,DocumentBuilder
,Document
,StreamSource
,Transformer
,Source
,Result
)。
现在有两种方法可以使用:干净的代码方法或肮脏的测试方法。
最好的解决方案是为所使用的类提供一个依赖框架:
public class XmlToCsv {
@Inject
DocumentBuilderFactory factory;
@Inject
StreamSource stylesource;
@Inject
TransformerFactory transformerFactory;
public void xmlToCsv(String sourceXlsFile, String sourceCsvFile, String sourceXmlFile) throws Exception {
//define the files
File stylesheet = new File(sourceXlsFile);
File xmlSource = new File(sourceXmlFile);
//create the DocumentBuilder to parse the XML file
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xmlSource);
//input the stylesheet to transform the XML to
StreamSource stylesource = new StreamSource(stylesheet);
Transformer transformer = transformerFactory.newInstance().newTransformer(stylesource);
//write a new output file using the stylesheet format
Source source = new DOMSource(document);
Result outputTarget = new StreamResult(new File(sourceCsvFile));
transformer.transform(source, outputTarget);
}
}
现在可以通过将模拟注入到可注入字段中来完成测试:
@RunWith(MockitoJUnitRunner.class)
public class XmlToCsvTest {
@Mock
DocumentBuilderFactory factory;
@Mock
StreamSource style source;
@Mock
TransformerFactory transformerFactory;
@InjectMocks
XmlToCsv sut; // System Under Test
@Test
public void testOk() throws Exception {
// Mocks
DocumentBuilder documentBuilder = Mockito.mock(DocumentBuilder.class);
Document document = Mockito.mock(Document.class);
// Now you control all objects created in the class and you can test if the right methods are called
// when-clauses
Mockito.when(factory.newDocumentBuilder).thenReturn(documentBuilder);
Mockito.when(documentBuilder.parse(any(File.class)).thenReturn(document);
// Add all when's here
// now call the class
sut.xmlToCsv("", "", "");
// now verify all calls
verify(factory, times(1)).newDocumentBuilder();
verify(documentBuilder, times(1)).parse(any(File.class));
// etc.
}
}
肮脏的方法是使用PowerMockito。使用PowerMockito,您可以覆盖现有类的新方法。这确实是不得已的办法,我不建议这样做,但是当您无法更改源代码时就可以使用它。它看起来像这样:
@RunWith(PowerMockRunner.class)
@PrepareForTest({XmlToCsv.class, DocumentBuilderFactory.class})
public class XmlToCsvTest {
XmlToCsv sut;
@Test
public void testXmlToCsv() throws Exception {
DocumentBuilder documentBuilder = Mockito.mock(DocumentBuilder.class);
Document document = Mockito.mock(Document.class);
//when phase
PowerMockito.mockStatic(DocumentBuilderFactory.newInstance).thenReturn(documentBuilder);
Mockito.when(factory.newDocumentBuilder).thenReturn(documentBuilder);
Mockito.when(documentBuilder.parse(any(File.class)).thenReturn(document);
// now call the class
sut.xmlToCsv("", "", "");
//now verify
verify(documentBuilder, times(1)).parse(any(File.class));
}
}
如您所见,示例还不完整,但有所不同。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句