Jumpstart Testing with Mockito and JUnit5

Code under test

public interface DataRepository {
int[] retrieveAllData();
int getStoredSumById(int id);
void save(Object o);
}
public interface DataService {
int calculateSum();
void setDataRepository(DataRepository dataRepository);
int calculateNewSum(int id);
void save(Data o);
}
public class DataServiceImpl implements DataService {

private DataRepository dataRepository;

public void setDataRepository(DataRepository dataRepository) {
this.dataRepository = dataRepository;
}

public int calculateSum(){
int sum = 0;
for(int value : dataRepository.retrieveAllData()){
sum += value;
}
return sum;
}

public int calculateNewSum(int id){
int sum = dataRepository.getStoredSumById(id);
return sum + sum;
}

public void save(Data o){
o = new Data(o.getName().toUpperCase());
dataRepository.save(o);
}
}
public class Data {
private String name;
// constructors, getters and setters
}

Unit tests without Mockito annotations

@Test
public void calculateSum_Should_ReturnResult_When_DataIsProvided() {
//create service under test
DataService ms = new DataServiceImpl();

//mock repository to test service in isolation
DataRepository dataRepositoryMock = mock(DataRepository.class);
when(dataRepositoryMock.retrieveAllData())
.thenReturn(new int[]{1, 2, 3});

//set mock to service
ms.setDataRepository(dataRepositoryMock);

//call method under test
int result = ms.calculateSum();

//verify if method on the mock is called by service under test
//it is mostly used when a method that is called on a mock
//does not have a return
verify(dataRepositoryMock, times(1)).retrieveAllData();

//assert result
assertEquals(6, result);
}
@Test
public void calculateSum_Should_ReturnZero_When_DataIsEmpty() {
//create service under test
DataService ms = new DataServiceImpl();

//mock repository to test service in isolation
DataRepository dataRepositoryMock = mock(DataRepository.class);
when(dataRepositoryMock.retrieveAllData())
.thenReturn(new int[]{});

//set mock to service
ms.setDataRepository(dataRepositoryMock);

//call method under test
int result = ms.calculateSum();

//verify if method on the mock is called by service under test
verify(dataRepositoryMock, times(1)).retrieveAllData();

//assert result
assertEquals(0, result);
}
@Test
public void calculateSum_Should_ThrowException_When_DataIsNull() {
assertThrows(NullPointerException.class, () -> {
//create service under test
DataService ms = new DataServiceImpl();

//mock repository to test service in isolation
DataRepository dataRepositoryMock =
mock(DataRepository.class);
when(dataRepositoryMock.retrieveAllData()).thenReturn(null);

//set mock to service
ms.setDataRepository(dataRepositoryMock);

//call method under test
ms.calculateSum();
});
}
@Test
void calculateNewSum_Should_ReturnResult_When_DataIsProvided() {
//create service under test
DataService ms = new DataServiceImpl();

//mock repository to test service in isolation
DataRepository dataRepositoryMock = mock(DataRepository.class);

//return 2 when method is called with any int value
when(dataRepositoryMock.getStoredSumById(anyInt()))
.thenReturn(2);

//set mock to service
ms.setDataRepository(dataRepositoryMock);

//call method under test
int result = ms.calculateNewSum(1);

//verify if method on the mock is called by
//service under test with any argument
verify(dataRepositoryMock, times(1)).getStoredSumById(anyInt());

//assert result
assertEquals(4, result);
}
@Test
void save_ShouldCallRepository_With_GivenParam() {
// create service under test
DataService ms = new DataServiceImpl();

// mock repository to test service in isolation
DataRepository dataRepositoryMock = mock(DataRepository.class);

// set mock to service
ms.setDataRepository(dataRepositoryMock);

// call method under test
Data o = new Data("MockitoObject");
ms.save(o);

//create expected object
Data expected = new Data("MOCKITOOBJECT");

// because the method does not return anything we can check
// if mock method was called with an expected parameter
ArgumentCaptor<Data> captor =
ArgumentCaptor.forClass(Data.class);
verify(dataRepositoryMock, times(1)).save(captor.capture());

//assert captured argument
assertEquals(expected, captor.getValue());
}

Cleaner unit tests without Mockito annotations

public class DataServiceTest_Clean {
//create service under test
DataService ms = new DataServiceImpl();

//mock repository to test service in isolation
DataRepository dataRepositoryMock = mock(DataRepository.class);

@BeforeEach
public void beforeEach(){
//set mock to service
ms.setDataRepository(dataRepositoryMock);
}

@Test
public void calculateSum_Should_ReturnResult_When_Data() {
//mock repository to test service in isolation
when(dataRepositoryMock.retrieveAllData())
.thenReturn(new int[]{1, 2, 3});

//call method under test
int result = ms.calculateSum();

//verify if method on the mock is called by
//service under test
//it is mostly used when a method that is
//called on a mock does not have a return
verify(dataRepositoryMock, times(1)).retrieveAllData();

//assert result
assertEquals(6, result);
}
}

Unit tests with Mockito annotations

@ExtendWith(MockitoExtension.class)
public class DataServiceTest_Clean_WithAnnotations {
//create service under test and inject all mocks needed
//there is no need to manually inject
//mockitoRepositoryMock, just create it with @Mock
@InjectMocks
DataServiceImpl ms;

//mock repository to test service in isolation
@Mock
DataRepository dataRepositoryMock;

@Test
void calculateSum_Should_ReturnResult_When_DataIsProvided() {
//mock repository to test service in isolation
when(dataRepositoryMock.retrieveAllData())
.thenReturn(new int[]{1, 2, 3});

//call method under test
int result = ms.calculateSum();

//verify if method on the mock is called
//by service under test
//it is mostly used when a method that is called
//on a mock does not have a return
verify(dataRepositoryMock, times(1)).retrieveAllData();

//assert result
assertEquals(6, result);
}
}

More on testing

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
WeInspire Technologies

WeInspire Technologies

Written by Gabriel Voicu — Senior Principal Lead Software Engineer @ Dell Technologies