powered by ASAP

1. What You Will Learn

In this guide you will learn how to write UnitTests for Java Commands with Services and how to test it with Mockito. This allows you to test the Command without implementing the interfaces to other components, so you can test it separately.

2. Prerequisites

To complete this guide you need:

  • Roughly 10 minutes

  • JDK11+ installed with JAVA_HOME configured appropriately

  • An IDE (we recommend IntelliJ)

  • Some kind of build tool (like Gradle, Maven or Apache Ant)

  • Read the UnitTest Simple Java Command guide

  • JUnit 5 environment

3. Dependencies

To write UnitTests for a Command we need to include some dependencies:

Dependencies Reason to include

de.asap.pak.jlcint:jlcint-commandapi

Provides annotations used to develop a Java Command

de.asap.pak.jlcint:jlcint-testutils

Utilities that allow the testing of Java Commands

org.junit.jupiter:junit-jupiter

Allows the writing of JUnit5 tests

org.junit.jupiter:junit-jupiter-engine

org.mockito:mockito-inline

Allows the simulation of non implemented interfaces from other components by using mock objects instead

org.mockito:mockito-junit-jupiter

4. The Service

A Service is usually defined by a set of interfaces and classes. The Service contains an interface or an abstract class that defines the functionality provided by the Service. The classes which use an interface have to implement the methods which are defined in the interface.

4.1. @Service

The @Service annotation declares that a Service should be injected at the annotated field.

4.2. UnitTest with Service and Mockito

Command Class Test Class
@JavaCommand
@CommandGroup("org.example")
class WriteValueToCell {

	@Service (2)
	private IMSOfficeAdapter officeAdapter;

	@Persistent
	private Object cellContent;

	@Persistent
	private String filePath;

	@Persistent
	private String cellAddress;

	@Persistent(mandatory = false)
	private String excelSheet = "Table1";

	@Run
	public void runWriteCellValue() {
		...
	}
}
@ExtendWith({ MockitoExtension.class, JlcintExtension.class }) (1)
class WriteValueToCellTest {

	@Service (2)
	@Mock (3)
	private IMSOfficeAdapter officeAdapter;

	@Mock (3)
	private ExcelService mockService;

	@Persistent
	private Object cellContent;

	@Persistent
	private String filePath;

	@Persistent
	private String cellAddress;

	@Persistent(mandatory = false)
	private String excelSheet = "Table1";

	private Provider<WriteValueToCell> command;
}
1 Additional to the JlcintExtension the MockitoExtension which is provided by the mockito-junit-jupiter dependency is needed. The MockitoExtension provides the ability to use the @Mock annotation.
2 The Service under test is annotated with @Service and is usually an interface of an adapter.
3 The IMSOfficeAdapter and its ExcelService are simulated as mock objects for testing.
The @Persistent-Annotation of the Command Fields need to be mirrored 1 to 1. For the test class it is sufficient to have a simple annotation over the input and output fields. So @Persistent and for output fields the scope will be enough.

4.3. UnitTest with Mocked Services

Now the WriteValueToCellTest Command can be tested in a simulated environment with no real existing ExcelService object. Only the ability to run the Command is tested by this UnitTest. Therefore, we write the following test.

class WriteValueToCellTest {
	@Service
	@Mock
	private IMSOfficeAdapter officeAdapter;
	@Mock
	private ExcelService mockService;
	@Persistent
	private Object cellContent;
	@Persistent
	private String filePath;
	@Persistent
	private String cellAddress;
	@Persistent(mandatory = false)
	private String excelSheet = "Table1";
	private Provider<WriteValueToCell> command;

	@Test
	void runWriteCellValueAddress() {
		// Set attributes
        this.cellContent = 5.5;
        this.filePath = "C:\\workspace\\ExcelFile.xlsx";
		this.cellAddress = "A1";
		this.excelSheet = "Table2";

		// Mock adapter (1)
		Mockito.when(this.officeAdapter.getExcelService()).thenReturn(this.mockService);

		this.command.execute();

		// Check the result of mocking test (2)
		Mockito.verify(this.mockService).writeCellValue(this.filePath, this.cellAddress, this.excelSheet, this.cellContent);
	}
}
1 With this Mockito Command the real ExcelService object will be replaced by a mock object.
2 The mock object is checked if it is called correctly with the predefined attributes.

Now you can run the test and see if the Command will be able to run in general.

5. Summary

In this guide we have learned how to write a UnitTest to run a Java Command using a Service. Additional the UnitTest with Mockito shows how to replace the Service object by a mock object.