То, что вы пытаетесь сделать, на самом деле не способ сделать это. Вы должны проверять ТОЛЬКО класс XmlToCsv
, а не классы, используемые этим классом (DocumentBuilderFactory
, DocumentBuilder
, Document
, StreamSource
, Transformer
, Source
, Result
).
Теперь есть 2 способа: чистый код или грязный тест.
Лучшее решение - у вас есть структура зависимостей для используемых вами классов:
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));
}
}
Как видите, примеры не завершены, но вы понимаете разницу.