How to Test Void Method with Junit Testing Tools

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



Leave a reply



Submit