How to unit test a method which calls a void method?
You use the verify method:
verify(myRemovalService).removeData("Test1"));
verify(myRemovalService).removeData("Test2"));
In Java, How to test void method in Junit Mockito with assertion?
You need to capture the value passed to the dao save method. Use mockito's ArgumentCaptor for that. Then assert on that value.
Something along these lines:
ArgumentCaptor<Detail> captor = ArgumentCaptor.forClass(Detail.class);
verify(dyDBDAO, times(2)).save(captor.capture());
Detail detail1 = captor.getValues().get(0)
assertEquals(expectedDetail, detail1)
How to test a void method using JUnit and/or Mockito
What you trying to do is actually not the way to do it. You should test ONLY the XmlToCsv
class and not the classes that are used by this class (DocumentBuilderFactory
, DocumentBuilder
, Document
, StreamSource
, Transformer
, Source
, Result
).
There are now 2 ways you can go: The clean code way, or the dirty test way.
The best solution is that you have a dependency framework for the classes you use:
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);
}
}
Testing now can be done by injecting mocks into the injectable fields:
@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.
}
}
The dirty way is using PowerMockito. With PowerMockito you can override the new methods of existing classes. It is really a last resort and I wouldn't recommend it, but you can use it when you can't change the source code. It will look something like this:
@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));
}
}
As you see the examples aren't complete, but you get the difference.
Testing a method with return type void
It is possible to test methods that don't return anything (void
), but you must test that method's side effects. It should have some side effects, otherwise such a method is useless.
The side effect here is that al
is changed. As written, this class doesn't have any other methods that expose al
. Add a getter method that returns either the ArrayList
or a specific element of the ArrayList
. Then your test method can call the getter method to retrieve the value(s) and compare it(them) with the expected value(s).
Related Topics
Eclipse Error: "Failed to Connect to Remote Vm"
Declaring and Initializing Variables Within Java Switches
The Server Time Zone Value 'Aest' Is Unrecognized or Represents More Than One Time Zone
How to Convert a Byte Array into a Double and Back
Invalid Thread Access Error with Java Swt
Variable's Scope in a Switch Case
How to Convert Binary String Value to Decimal
Java.Lang.Classcastexception Using Lambda Expressions in Spark Job on Remote Server
How to Get the Desktop Path in Java
In Java, When Does an Object Become Unreachable
How to Flatten 2D Array to 1D Array
Get the Changed HTML Content After It's Updated by JavaScript? (Htmlunit)
Load Resource from Anywhere in Classpath