Unit testing with mocks

Let's start with understanding what mocking is. Mocking is creating objects that simulate the behavior of real objects. In the previous example, in the unit test, we would want to simulate the behavior of DataService.

Unlike stubs, mocks can be dynamically created at runtime. We will use the most popular mocking framework, Mockito. To understand more about Mockito, we recommend the Mockito FAQ at https://github.com/mockito/mockito/wiki/FAQ.

We will want to create a mock for DataService. There are multiple approaches to creating mocks with Mockito. Let's use the simplest among them—annotations. We use the @Mock annotation to create a mock for DataService:

    @Mock 
private DataService dataServiceMock;

Next, we want BusinessServiceImpl to make use of the mock. We can do that using the @InjectMocks annotation. @InjectMocks will ensure that all of the dependencies of the service are autowired:

    @InjectMocks 
private BusinessService service = new BusinessServiceImpl();

BusinessServiceImpl will call the retrieveData method on dataService. We will need to make the mock return test data when this method is called. We will use the BDD style methods provided by Mockito to mock the retrieveData method:

    BDDMockito.given(
dataServiceMock.retrieveData(Matchers.any(User.class)))
.willReturn(
Arrays.asList(new Data(10), new Data(15), new Data(25)));

When the retrieveData method is called on the dataService mock with any object of type User, it returns a list of three items with values specified.

When we use Mockito annotations, we will need to use a specific JUnit runner, that is, MockitoJunitRunner. MockitoJunitRunner helps to keep the test code clean and provides clear debugging information in case of test failures. MockitoJunitRunner initializes the beans annotated with the @Mock annotation and validates the usage of the framework after the execution of each test method:

    @RunWith(MockitoJUnitRunner.class)

The complete list of the test is as follows. It has one test method:

    @RunWith(MockitoJUnitRunner.class) 
public class BusinessServiceMockitoTest {

private static final User DUMMY_USER = new User("dummy");

@Mock
private DataService dataServiceMock;

@InjectMocks
private BusinessService service = new BusinessServiceImpl();

@Test
public void testCalculateSum() {
BDDMockito
.given(
dataServiceMock.retrieveData(Matchers.any(User.class)))
.willReturn(
Arrays.asList(new Data(10), new Data(15), new Data(25)));

long sum = service.calculateSum(DUMMY_USER);

assertEquals(10 + 15 + 25, sum);

}

}

Writing unit tests with mocks is made simple by the @Mock and @InjectMocks annotations.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset