Null Check In Java

Java has evolved over the years. Below are few of the methods to check whether an object is Null or not in Java.

Java 5

Before Java 8 we were able to check for an object being Null by using a simple `if` statement, as shown in code below:

        public void preJava8(String s) {
            if (s == null) {
                // do something
                System.out.println("String is null");
            }
            System.out.println("String is not null");
        }  
    

Java 8

With introduction of `Optional` class in Java 8, we can use it to perform actions on an object if its value is not null.
        public void java8Optional(String s) {
            Optional.ofNullable(s)
                    .ifPresent((str) -> {
                        //do something
                        System.out.println("String is not null");
                    });
        }

Java 9


Java 9 enhances the Optional class to provide an else condition to ifPresent() method of Optional in Java 8.
        public void java9Optional(String s) {
            Optional.ofNullable(s)
                    .ifPresentOrElse(
                            (str) -> {
                                //do something
                                System.out.println("String is not null");
                            },
                            () -> {
                                //do something
                                System.out.println("String is null");
                            });
        }
    

Full code can be found in our Github repository.

Junit5 Parametrized Tests

 What are parameterized unit tests and How to write them using Junit5?

In this article we will learn about parameterized tests and how to write Junit parameterized tests. The parameterized tests is the concept of running a single test multiple times, but with different parameters and outcomes. The parameterized unit tests allow us to avoid writing same code multiple times.

JUnit 5, the newest version of JUnit, adds a slew of new capabilities to make creating developer tests easier.

Parameterized tests are one such feature. This feature allows us to repeat a test procedure with varied parameters many times.

To start writing parameterized tests, we first need to include `junit-jupiter-params` dependency in our project.

For Maven, add below dependency to the project's pom.xml file.


<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-params</artifactId>
    <version>5.7.0</version>
    <scope>test</scope>
</dependency>

Let's consider the following class, with a utility method to verify if an integer is odd number or not.

IntegerUtils.java

public final class IntegerUtils {

    public static boolean isOdd(int number) {
        return number % 2 != 0;
    }
}

We can write a simple unit test that will invoke the `isOdd()` method of the util class with various number of options and verify it's working.

Let's consider the following class, with a utility method to verify if an integer is odd number or not.

IntegerUtilsTest.java

class IntegerUtilsTest {

    @ParameterizedTest
    @ValueSource(ints = {1, 3, 5, -3, 15, Integer.MAX_VALUE})
    void test_odd_numbers(int value) {
        Assertions.assertTrue(IntegerUtils.isOdd(value));
    }

    @ParameterizedTest
    @ValueSource(ints = {0, 2, 1000, -30, 150, (Integer.MAX_VALUE - 1)})
    void test_even_numbers(int value) {
        Assertions.assertFalse(IntegerUtils.isOdd(value));
    }
}

Above is a very simple example of how parameterization works in Junit5 framework.  In further articles, we will explore different variations of parameterized unit tests supported by Junit5 framework.

Full source code can be found in our Github Repository.


Test Callback Invocation using Junit5 and Mockito

In this article we will use thenAnswer method of Mockito to invoke a callback method passed to a mock. 

Let's consider following classes.

Here, ServiceToBeTested class is calling submitCallback() method of ServiceToBeMocked class and passing it a Callback object.

The value set in Callback object is latter returned by the method being tested.

ServiceToBeTested.java

public class ServiceToBeTested {

    private final ServiceToBeMocked serviceToBeMocked;

    public ServiceToBeTested(ServiceToBeMocked serviceToBeMocked) {
        this.serviceToBeMocked = serviceToBeMocked;
    }

    public String methodToBeTested() {
        Callback callback = new Callback();
        serviceToBeMocked.submitCallback(callback);

        return "Value Received after callback = " + callback.getValue();
    }
}
ServiceToBeMocked.java

public class ServiceToBeMocked {

    public void submitCallback(Callback callback) {
        //some logic that sets value back in callback.
        callback.setValue(null);
    }
}
Callback.java

/**
 * Simple class demonstrating callback events. The implementation could be much more complex.
 */
public class Callback {

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

In above scenario, thenReturn method of Mockito will be of no use. We can use thenAnswer() method in this case to achieve our test scenario.

ServiceToBeTestedTest.java

@ExtendWith(MockitoExtension.class)
class ServiceToBeTestedTest {

    @Mock
    private ServiceToBeMocked serviceToBeMocked;

    @InjectMocks
    private ServiceToBeTested serviceToBeTested;

    @Test
    void test_callback() {
        Mockito.doAnswer(it -> {
            Callback callback = it.getArgument(0);
            callback.setValue("Mocked Value");
            return null;
        }).when(serviceToBeMocked).submitCallback(Mockito.any(Callback.class));

        String returnValue = serviceToBeTested.methodToBeTested();

        Assertions.assertEquals("Value Received after callback = Mocked Value", returnValue);
    }
}

Full sample code can be found at our Github repository.

How to verify values passed to a mocked method?

 In this tutorial we will learn how we can verify values passed to a method.

Many times we want to verify values passed to a method while execution of the method being tested. This situation may arise when invoked method has no effect on the calling method. Eg. Publishing an event.

Let's take a look at the following example, where the `updateBalance()` method is calling `NotificationService` method to publish an event.

AccountService.java

public class AccountService {
    private final NotificationService notificationService;

    public void updateBalance(String accountNumber, BigDecimal newBalance) {
        // some calculations
        notificationService.publish(new AccountUpdatedEvent(accountNumber, newBalance));
    }
}


NotificationService.java

public class NotificationService {

    /**
     * Publish an event to the message broker
     *
     * @param event
     */
    public void publish(Event event) {
        // logic here to write to message broker
    }
}

Now if we want to test that an AccountUpdateEvent, containing correct account number and balance is being passed to the NotificationService, we can use ArgumentCaptor.

AccountServiceTest.java

@ExtendWith(MockitoExtension.class)
class AccountServiceTest {

    @Captor
    private ArgumentCaptor<AccountUpdatedEvent> accountUpdatedEventCaptor;

    @Mock
    private NotificationService notificationService;

    @InjectMocks
    private AccountService accountService;

    @Test
    void verify_update_event() {
        final String accountNumber = "636636636";
        final BigDecimal newBalance = BigDecimal.valueOf(1000000L);

        accountService.updateBalance(accountNumber, newBalance);

        Mockito.verify(notificationService).publish(accountUpdatedEventCaptor.capture());

        AccountUpdatedEvent accountUpdatedEvent = accountUpdatedEventCaptor.getValue();
        Assertions.assertEquals(accountNumber, accountUpdatedEvent.getAccountNumber());
        Assertions.assertEquals(newBalance, accountUpdatedEvent.getBalance());
    }

}


Full source code can be found on Github.


Setup Lombok with Spring Boot

 Lombok is a Java library that takes care of generating lot of this boiler plate code for the developers.

Lombok works by plugging into your build process and hooking into Java byte-code generation stage, to add required code based on your specifications. Lombok uses annotations to identify which piece of code needs to be auto generated.

Adding Lombok to any project is very simple. You simply have to include the  Lombok package in your build path. 

If you are using Spring boot, Lombok version will be resolved for you by Spring.

Maven pom.xml

    <parent>
        <groupid>org.springframework.boot</groupid>
        <artifactid>spring-boot-starter-parent</artifactid>
        <version>2.3.12.RELEASE</version>
        <relativepath>
    </relativepath></parent>

    <dependencies>
        <!--https://mvnrepository.com/artifact/org.projectlombok/lombok-->
        <dependency>
            <groupid>org.projectlombok</groupid>
            <artifactid>lombok</artifactid>
            <scope>provided</scope>
        </dependency>
    </dependencies>

Lombok Sample Person.java


@Data
public class Person {
    private String name;
    private int age;
}

Unit Test PersonTest.java


class PersonTest {

    @Test
    public void data_annotation() {
        Person person = new Person();
        person.setName("David Hoff");
        person.setAge(25);

        Assertions.assertEquals("David Hoff", person.getName());
        Assertions.assertEquals(25, person.getAge());
    }
}

The entire sample code can be found on Github

Adding Custom Validation in Lombok Builder

What is Lombok?

Lombok is a Java library that auto generates lots of boiler plate code for Java classes. Lombok works at compile time and manipulates Java byte code to add additional features. Lombok uses annotations to specify what boiler plate code will be generates. Eg. @Getter annotation can be applied to any Java bean to auto generate Getter methods for all the fields in that bean.

In this article we will be looking at, how to add custom validations on fields using Lombok Builder annotation

What is Builder annotation in Lombok?

Lombok can be used to generate Builder class for a Java bean, by annotating the bean class with @Builder annotation. 

In certain cases, we might want to validate the data, in builder class, before creating the bean object. Lombok provides simple validator annotations like @NonNull to enforce nullability checks. But what if, we want to have more custom validations or want to throw custom errors.

Customizing Lombok Builder class.

Let's consider below Employee class that requires custom format for `employeeId` field. Also, present in the class, is custom builder that performs validations in the `build()` method.

Employee.java

@Getter
@Builder
public class Employee {

    @NonNull
    private final String name;

    /**
     * Let's add following validations:
     * 1. Employee Id must start with `P` or `T`
     * 2. Must be of length 5
     */
    private final String employeeId;

    @NonNull
    private final LocalDate joiningDate;

    // ##########################################
    // Below we add the custom code to validate employeeId
    // ##########################################

    /**
     * Override the builder() method to return our custom builder instead of the Lombok generated builder class.
     *
     * @return
     */
    public static EmployeeBuilder builder() {
        return new CustomBuilder();
    }

    /**
     * Customized builder class, extends the Lombok generated builder class and overrides method implementations.
     */
    private static class CustomBuilder extends EmployeeBuilder {

        /**
         * Adding validations as part of build() method.
         *
         * @return
         */
        public Employee build() {

            if (super.employeeId == null || super.employeeId.trim().length() != 5) {
                throw new RuntimeException("Employee Id must be of 5 characters");
            }

            final char firstCharacter = super.employeeId.toCharArray()[0];
            if (firstCharacter != 'P' && firstCharacter != 'T') {
                throw new RuntimeException("Employee Id must begin with character `P` or `T`");
            }

            return super.build();
        }
    }
}

We can test the working of the above Employee class using below unit tests.

EmployeeTest.java

class EmployeeTest {

    /**
     * Create Employee object with valid data.
     */
    @Test
    public void valid_data() {
        Employee employee = Employee.builder()
                .name("James Wittel")
                .joiningDate(LocalDate.now())
                .employeeId("P1234")
                .build();

        Assertions.assertNotNull(employee);
    }

    /**
     * Creating employee object with null employee Id should generate error.
     */
    @Test
    public void null_employee_id() {
        Assertions.assertThrows(
                RuntimeException.class,
                () -> Employee.builder()
                        .name("James Wittel")
                        .joiningDate(LocalDate.now())
                        .employeeId(null)
                        .build());
    }

    /**
     * Creating employee object with invalid length employee Id should generate error.
     */
    @Test
    public void invalid_length_employee_id() {
        Assertions.assertThrows(
                RuntimeException.class,
                () -> Employee.builder()
                        .name("James Wittel")
                        .joiningDate(LocalDate.now())
                        .employeeId("P938838838")
                        .build());
    }

    /**
     * Creating employee object with invalid starting character of employee Id, should generate error.
     */
    @Test
    public void invalid_start_character_employee_id() {
        Assertions.assertThrows(
                RuntimeException.class,
                () -> Employee.builder()
                        .name("James Wittel")
                        .joiningDate(LocalDate.now())
                        .employeeId("A9388")
                        .build());
    }
}

How to mock void methods with Mockito

How to mock void methods with Mockito while writing unit tests in Java?

Some times the method you are unit testing, has a dependency on a method that does not return any value, but has a void return type. To mock such methods we can not use the `when-thenReturn` or `doReturn-when` pattern. 

Our simple expectation from the `Void` dependency method could be that it throws an exception or does not perform any internal action.

Mockito provides two constructs `doThrow-when` and `doNothing-when` to test the above scenarios.


Mockito.doThrow(new Exception()).when(mockObject).methodName();

Mockito.doNothing().when(mockObject).methodName();

Let's look at an example to understand the above two scenarios.

Let's consider our PersonService class and PersonRepository class. We would be writing unit tests for the `delete()` method of PersonService class. The `delete()` method of PersonService class is dependent on `delete()` method of PersonRepository class, which has return type as `void`. PersonRepository is a Spring JPA repository, hence it provides these methods implicitly.

PersonService
public class PersonService {

    private final PersonRepository personRepository;

    public PersonService(PersonRepository personRepository) {
        this.personRepository = personRepository;
    }

    public void delete(Long id) {
        Person person = new Person();
        person.setId(id);
        personRepository.delete(person);
    }
}
  


PersonRepository
public interface PersonRepository extends JpaRepository<Person, Long> {
}
  

The following test class shows how to write unit test to check for success and exception case.

PersonServiceTest
class PersonServiceTest {

    /**
     * Verify successful execution of tested method, by setting dependency method to do nothing.
     */
    @Test
    void create_success() {
        // Create mock of PersonRepository
        PersonRepository mockPersonRepository = Mockito.mock(PersonRepository.class);

        // Create PersonService class and inject mocked PersonRepository object to it.
        PersonService personService = new PersonService(mockPersonRepository);

        // Setup do nothing expectation of PersonRepository
        Mockito.doNothing().when(mockPersonRepository).delete(Mockito.any(Person.class));

        // Call tested method
        personService.delete(34L);

        // Verify that delete() method of PersonRepository was called by the delete() method od PersonService.
        Mockito.verify(mockPersonRepository).delete(Mockito.any(Person.class));
    }

    /**
     * Verify exception is throw by the tested method if dependent method throws exception.
     */
    @Test
    void create_exception() {
        // Create mock of PersonRepository
        PersonRepository mockPersonRepository = Mockito.mock(PersonRepository.class);

        // Create PersonService class and inject mocked PersonRepository object to it.
        PersonService personService = new PersonService(mockPersonRepository);

        // Setup expectation of delete() method of PersonRepository to throw exception
        Mockito.doThrow(new RuntimeException("Invalid Argument")).when(mockPersonRepository).delete(Mockito.any(Person.class));

        // Call tested method, and verify that it throws an exception
        Assertions.assertThrows(RuntimeException.class, () -> personService.delete(100L));
    }
}
  


How to verify method arguments using Mockito

 How to verify value of an argument passed to a mocked method?

While writing unit tests, we might need to verify the parameters passed to a dependency method, from the method being tested. Mockito provides an easy way to achieve this. 

Mockito provides ArgumentMatcher class that can be used to verify arguments passed to a mocked method.

We will be using the UserService and UserRepository class in this example. UserService is the class that is being unit tested and UserRepository is a dependency class that has to be mocked.

UserService
@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    /**
     * Save a user in database
     *
     * @param id
     * @return
     */
    public Optional<User> findById(Long id) {
        if (id == null) {
            throw new RuntimeException("Id is required");
        }
        return userRepository.findById(id);
    }
}


UserRepository
public interface UserRepository extends JpaRepository<User, Long> {
}


The ArgumentMatcher, is a functional interface, that we can pass as the part of the `Mockito.verify()` calls to access parameters passed to a mock and perform checks over it.

Now, let's see our example test class, where we are verifying that the argument passed to the findById() method of UserRepository is equal to 100. In this example, we will use `Mockito.argThat()` method and pass it a custom implementation of an ArgumentMatcher to verify parameter value.

UserServiceArgumentMatcherTest
/**
 * In this example we will use ArgumentMatchers to verify the values passed to a mock method as parameters.
 */
class UserServiceArgumentMatcherTest {

    @Test
    void verify_argument() {
        // Create a mock object for dependency class
        UserRepository mockUserRepository = Mockito.mock(UserRepository.class);

        // Add mocked dependency to the class object being tested
        UserService userService = new UserService(mockUserRepository);

        // Use when-thenReturn format to specify return value for invoked method on mock
        Mockito.when(mockUserRepository.findById(100L)).thenReturn(Optional.of(new User(100L)));

        // Invoke the method to be tested
        userService.findById(100L);

        // Verify that we have called findById() method of UserRepository with correct arguments
        Mockito.verify(mockUserRepository).findById(Mockito.argThat((Long id) -> id == 100L));
    }
}


How to specify return value from a method using Mockito

Mockito allows you to specify what to return when a method is called on a mocked object. Mockito supports two ways to do it: `when-thenReturn` and `doReturn-when`. In most cases, `when-thenReturn` is used and has better readability.

Below is the example usage for testing our UserService class that has dependency on UserRepository class.

UserServiceReturnOptionsTest
/**
 * Test class to show example implementation of when-thenReturn and doReturn-when pattern of Mockito to define return
 * types from a mocked method.
 */
class UserServiceReturnOptionsTest {

    /**
     * This method used when-thenReturn pattern to set return value from a mock object
     */
    @Test
    void when_then_example() {
        // Create a mock object for dependency class
        UserRepository mockUserRepository = Mockito.mock(UserRepository.class);

        // Add mocked dependency to the class object being tested
        UserService userService = new UserService(mockUserRepository);

        // Use when-thenReturn format to specify return value for invoked method on mock
        Mockito.when(mockUserRepository.findById(100L)).thenReturn(Optional.of(new User(100L)));

        // Invoke the method to be tested
        Optional<User> userOptional = userService.findById(100L);

        // Check return value is as expected
        Assertions.assertTrue(userOptional.isPresent());
        Assertions.assertEquals(100L, userOptional.get().getId());
    }

    /**
     * This method used doReturn-when pattern to set return value from a mock object
     */
    @Test
    void doReturn_when_example() {
        // Create a mock object for dependency class
        UserRepository mockUserRepository = Mockito.mock(UserRepository.class);

        // Add mocked dependency to the class object being tested
        UserService userService = new UserService(mockUserRepository);

        // Use doReturn-when format to specify return value for invoked method on mock
        Mockito.doReturn(Optional.of(new User(200L))).when(mockUserRepository).findById(200L);

        // Invoke the method to be tested
        Optional<User> userOptional = userService.findById(200L);

        // Check return value is as expected
        Assertions.assertTrue(userOptional.isPresent());
        Assertions.assertEquals(200L, userOptional.get().getId());
    }
}

In the above example we can see that both the patterns are very similar. But each has its own advantage. 

The `when-thenReturn` has the advantage of compile time type checking, whereas `doReturn-when` does not.  That means if we specify wrong return type as part of thenReturn() method, we would get a compile time error. Where as a wrong return type in doReturn() will fail only at runtime.

// won't compile
Mockito.when(mockUserRepository.findById(100L)).thenReturn(true);

// Will compile successfully but fail during execution of test.
Mockito.doReturn(true).when(mockUserRepository).findById(200L);


The when() method in `when-thenReturn` ends up invoking the method passed to it i.e. `mockUserRepository.findById(100L)` in example above. This is not a problem when we are using a mock object, since all its method have empty implementation. But this becomes a problem if we use `when-thenReturn` on a spy object created using `Mockito.spy()` method. In that case all the methods retain their actual implementation unless an expectation is defined for them.

The `doReturn-when` pattern is the preferred choice when specifying expectation on a spy object.

// will execute original method, hence can generate error
Mockito.when(mockUserRepository.findById(100L)).thenReturn(Optional.of(new User(200L)));

// Does not execute original method, hence no side effects.
Mockito.doReturn(Optional.of(new User(200L))).when(mockUserRepository).findById(200L);


How to verify that a method is called using Mockito

As part of writing unit tests, many times we might need to verify that the tested method is calling an external dependency method.

Let's consider the following UserServer and UserRepository classes. UserService class is dependent on UserRepository class for fetching a User object with given Id. While writing a unit test for findById() method, it makes sense to verify that findById() method of UserRepository is actually invokes.

UserService

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    /**
     * Save a user in database
     *
     * @param id
     * @return
     */
    public Optional<User> findById(Long id) {
        if (id == null) {
            throw new RuntimeException("Id is required");
        }
        return userRepository.findById(id);
    }
}
  
UserRepository

public interface UserRepository extends JpaRepository<User, Long> {
}
  

Mockito provides a convenient way of verifying if a particular method was invokes on the mocked class or not. A point to remember here is that the object on which verify is called, must be a mock object created by Mockito. The simplest case to verify that a method of a mocked object is invoked or not is as below.

Mockito.verify(mockObject).methodToBeVerified(method_parameters);

UserServiceVerifyInvocationTest

class UserServiceVerifyInvocationTest {

  @Test
  void simple_mock() {
      // Create a mock object using Mockito.
      UserRepository mockedUserRepository = Mockito.mock(UserRepository.class);

      // Inject mock implementation of UserRepository as dependency to UserService method.
      UserService userService = new UserService(mockedUserRepository);

      // define expectation from the findById() method of UserRepository mock object
      Mockito.doReturn(Optional.of(new User(100L)))
              .when(mockedUserRepository)
              .findById(100L);

      // When the tested method is invoked.
      Optional<User> result = userService.findById(100L);

      // Then the dummy User object should be returned.
      Assertions.assertTrue(result.isPresent());
      Assertions.assertEquals(100L, result.get().getId());

      // And verify that findById() method of UserRepository was invoked.
      Mockito.verify(mockedUserRepository).findById(100L);
  }
}
  


The other options to verify method invocation are as below:

  • Verify specific method is called multiple number of times

Mockito.verify(mockObject, Mockito.times(n)).methodToBeVerified(method_parameters);
  
  • Verify no interaction with specific method

Mockito.verify(mockObject, Mockito.never()).methodToBeVerified(method_parameters);
  
  • Verify no interaction with any method of the mock

Mockito.verifyZeroInteractions(mockObject);
  
  • Verify interaction with only specific method and no other interaction

Mockito.verify(mockObject).methodToBeVerified(method_parameters);
Mockito.verifyNoMoreInteractions(mockObject);
  

How to mock a dependency using Mockito in JUnit

 How to mock and inject dummy implementation using Mockito for Unit Testing?

In this article we will explore the various ways of defining a mock implementation for a dependency class in Unit Tests.

For writing Unit Tests, we have to decouple the tested class from any of its dependencies. Mockito provides us an easy way to define mock implementation and control response from a dependency class/method.


UserService.java

  package com.devnips.mockitojunit5.service;

import com.devnips.mockitojunit5.model.User;
import com.devnips.mockitojunit5.repository.UserRepository;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    /**
     * Save a user in database
     *
     * @param id
     * @return
     */
    public Optional<User> findById(Long id) {
        if (id == null) {
            throw new RuntimeException("Id is required");
        }
        return userRepository.findById(id);
    }
}
  
UserRepository.java

  package com.devnips.mockitojunit5.repository;

import com.devnips.mockitojunit5.model.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
}
  
Now let's see various options on how to write a Unit Test for UserServer.java class by mocking UserRepository.java dependency.

1. Simple Mock

In this method we create a mock object programatically by using the 

public static <T> T mock(Class<T> classToMock)

method of Mockito.java class.

UserServiceSimpleMockTest.java

  import com.devnips.mockitojunit5.model.User;
import com.devnips.mockitojunit5.repository.UserRepository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import java.util.Optional;

class UserServiceSimpleMockTest {

    @Test
    void simple_mock() {
        // Create a mock object using Mockito.
        UserRepository mockedUserRepository = Mockito.mock(UserRepository.class);

        // Inject mock implementation of UserRepository as dependency to UserService method.
        UserService userService = new UserService(mockedUserRepository);

        // define expectation from the findById() method of UserRepository mock object
        Mockito.doReturn(Optional.of(new User(100L)))
                .when(mockedUserRepository)
                .findById(100L);

        // When the tested method is invoked.
        Optional<User> result = userService.findById(100L);

        // Then the dummy User object should be returned.
        Assertions.assertTrue(result.isPresent());
        Assertions.assertEquals(100L, result.get().getId());
    }
}

  

2. Mock with default response for methods.

Mockito provides an overloaded implementation of the mock() method which accepts an Answer object to define default expectation from mock methods.
public static <T> T mock(Class<T> classToMock, Answer defaultAnswer)

We use the above method to create a mock object as shown below.

UserServiceMockWithAnswerTest.java

  import com.devnips.mockitojunit5.model.User;
import com.devnips.mockitojunit5.repository.UserRepository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.util.Optional;

/**
 * Here we create a simple mock object from Mockito and define default Answer for that mock object.
 */
class UserServiceMockWithAnswerTest {

    @Test
    void simple_mock() {
        // Create a mock object and set default answer for all methods.
        // This Answer implementation will be invoked if no expectation is defined for a method.
        UserRepository mockedUserRepository =
                Mockito.mock(UserRepository.class, new Answer() {
                    @Override
                    public Object answer(InvocationOnMock invocationOnMock) {
                        return Optional.of(new User(200L));
                    }
                });

        // Inject mock implementation of UserRepository as dependency to UserService method.
        UserService userService = new UserService(mockedUserRepository);

        // When the tested method is invoked.
        Optional<User> result = userService.findById(100L);

        // Then the default User object defined during creation of mock should be returned.
        Assertions.assertTrue(result.isPresent());
        Assertions.assertEquals(200L, result.get().getId());

        // define custom response for the findById() method of UserRepository mock object.
        // This will override the default Answer implementation.
        Mockito.doReturn(Optional.of(new User(100L)))
                .when(mockedUserRepository)
                .findById(100L);

        // Now when the tested method is invoked.
        Optional<User> customResult = userService.findById(100L);

        // Then the custom User object defined in doReturn method should be returned.
        Assertions.assertTrue(customResult.isPresent());
        Assertions.assertEquals(100L, customResult.get().getId());
    }
}
  


3. Using annotations


Mockito provides a JUnit extension class MockitoExtension that can be used to enable annotation processing and notify Mockito to create Mocks using annotations.

Here is a simple example of creating mock objects using annotations. This annotation processing method fits very well with Spring dependency injection.

UserServiceWithMockitoTest.java

  import com.devnips.mockitojunit5.model.User;
import com.devnips.mockitojunit5.repository.UserRepository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Optional;

/**
 * This test class shows how to mock a dependency class using Mockito annotations.
 * The below @ExtendWith annotation enabled the Mockito extension, which is required for processing annotations.
 */
@ExtendWith(MockitoExtension.class)
class UserServiceWithMockitoTest {

    /**
     * @Mock is an annotation provided by Mockito that creates a dummy implementation of the given class or interface.
     * Mockito uses Java's proxy pattern to create the dummy class.
     */
    @Mock
    private UserRepository userRepository;

    /**
     * @InjectMocks is a Mockito annotations that tells Mockito to create an actual instance of the given class and
     * also inject any dependencies that are defined with @Mock annotation.
     */
    @InjectMocks
    private UserService userService;

    @Test
    void findById_existing_id() {
        // Here we are defining the behaviour of given method in our Mock implementation.
        // We are telling Mockito to return a User object when `findById()` method of userRepository object is called
        // with parameter as 100L
        Mockito.doReturn(Optional.of(new User(100L)))
                .when(userRepository)
                .findById(100L);

        // When the tested method is invoked.
        Optional<User> result = userService.findById(100L);

        // Then the defined User object should be returned.
        Assertions.assertTrue(result.isPresent());
        Assertions.assertEquals(100L, result.get().getId());
    }

    @Test
    void findById_non_existent_id() {
        Mockito.doReturn(Optional.empty())
                .when(userRepository)
                .findById(200L);

        Optional<User> result = userService.findById(200L);

        Assertions.assertFalse(result.isPresent());
    }
}
  


Mocking external dependencies in Unit Tests using Mockito framework

 In the previous article we saw how we can decouple classes for Unit Testing by creating dummy classes.

In this article we will rewrite the same example using Mockito framework. Mockito makes it super easy to write dummy classes in a declarative way.

Let's take the same example of UserService and UserRepository classes. We are going to write a Unit Test for fineById() method of UserService class. We will mock and inject UserRepository as a dependency to UserService class.

UserService.java

package com.devnips.mockitojunit5.service;

import com.devnips.mockitojunit5.model.User;
import com.devnips.mockitojunit5.repository.UserRepository;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    /**
     * Save a user in database
     *
     * @param id
     * @return
     */
    public Optional findById(Long id) {
        if (id == null) {
            throw new RuntimeException("Id is required");
        }
        return userRepository.findById(id);
    }
}
UserRepository.java

package com.devnips.mockitojunit5.repository;

import com.devnips.mockitojunit5.model.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository {
}

Now we will write a Unit Test for UserService class using Mockito annotations.

UserServiceWithMockitoTest.java

package com.devnips.mockitojunit5.service;

import com.devnips.mockitojunit5.model.User;
import com.devnips.mockitojunit5.repository.UserRepository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Optional;

/**
 * This test class shows how to mock a dependency class using Mockito annotations.
 * The below @ExtendWith annotation enabled the Mockito extension, which is required for processing annotations.
 */
@ExtendWith(MockitoExtension.class)
class UserServiceWithMockitoTest {

    /**
     * @Mock is an annotation provided by Mockito that creates a dummy implementation of the given class or interface.
     * Mockito uses Java's proxy pattern to create the dummy class.
     */
    @Mock
    private UserRepository userRepository;

    /**
     * @InjectMocks is a Mockito annotations that tells Mockito to create an actual instance of the given class and
     * also inject any dependencies that are defined with @Mock annotation.
     */
    @InjectMocks
    private UserService userService;

    @Test
    void findById_existing_id() {
        // Here we are defining the behaviour of given method in our Mock implementation.
        // We are telling Mockito to return a User object when `findById()` method of userRepository object is called
        // with parameter as 100L
        Mockito.doReturn(Optional.of(new User(100L)))
                .when(userRepository)
                .findById(100L);

        // When the tested method is invoked.
        Optional result = userService.findById(100L);

        // Then the defined User object should be returned.
        Assertions.assertTrue(result.isPresent());
        Assertions.assertEquals(100L, result.get().getId());
    }

    @Test
    void findById_non_existent_id() {
        Mockito.doReturn(Optional.of(new User(100L)))
                .when(userRepository)
                .findById(100L);

        Optional result = userService.findById(200L);

        Assertions.assertFalse(result.isPresent());
    }
}

Mocking dependencies without using Mockito Framework

In this post, we will learn how we can create dummy implementation of a dependency class and use it in our Unit Test.

Let's consider following UserService class.

UserService.java

package com.devnips.mockitojunit5.service;

import com.devnips.mockitojunit5.model.User;
import com.devnips.mockitojunit5.repository.UserRepository;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    /**
     * Save a user in database
     *
     * @param id
     * @return
     */
    public Optional findById(Long id) {
        if (id == null) {
            throw new RuntimeException("Id is required");
        }
        return userRepository.findById(id);
    }
}

This class is a Spring bean and has dependency on UserRepository interface. UserRepository interface is again a Spring JPA bean. Spring JPA provides easy implementation of JPA based repositories to access database. Spring JPA uses auto configurations to initialize database connections. 

UserRepository.java

package com.devnips.mockitojunit5.repository;

import com.devnips.mockitojunit5.model.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository {
}

While testing UserService class, we need to remove dependency on UserRepository class, since we only want to test that the code in UserService class is working correctly. For testing any dependency class, we will write separate Unit Tests for that class. 

In Unit Tests we isolate each class and test its functionality individually.

To achieve this isolation we replace the actual implementation of the dependency class with a dummy one and override the methods to return static values as per our test requirement.

Below is an example, that provides dummy implementation of the UserRepository class and tests the findOneById(Long) method of UserService class.

UserRepository.java

package com.devnips.mockitojunit5.service;

import com.devnips.mockitojunit5.model.User;
import com.devnips.mockitojunit5.repository.UserRepository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import java.util.List;
import java.util.Optional;

public class UserServiceNoMockitoTest {

    private UserService userService;

    private MockUserRepository mockUserRepository = new MockUserRepository();

    @Test
    void findOneById_valid_id() {
        // Setup dummy behaviour
        userService = new UserService(new MockUserRepository() {
            @Override
            public Optional<User> findById(Long id) {
                if (id == 100L) {
                    return Optional.of(new User(id));
                } else {
                    return Optional.empty();
                }
            }
        });

        // When test method is called
        Optional<User> optionalUser = userService.findById(100L);

        // Then we should get non empty value
        Assertions.assertTrue(optionalUser.isPresent());
    }

    /**
     * Creating a dummy implementation of UserRepository.
     */
    class MockUserRepository implements UserRepository {

        @Override
        public List<User> findAll() {
            return null;
        }

        @Override
        public List<User> findAll(Sort sort) {
            return null;
        }

        @Override
        public Page<User> findAll(Pageable pageable) {
            return null;
        }

        @Override
        public List<User> findAllById(Iterable<Long> iterable) {
            return null;
        }

        @Override
        public long count() {
            return 0;
        }

        @Override
        public void deleteById(Long aLong) {

        }

        @Override
        public void delete(User user) {

        }

        @Override
        public void deleteAll(Iterable<? extends User> iterable) {

        }

        @Override
        public void deleteAll() {

        }

        @Override
        public <S extends User> S save(S s) {
            return null;
        }

        @Override
        public <S extends User> List<S> saveAll(Iterable<S> iterable) {
            return null;
        }

        @Override
        public Optional<User> findById(Long aLong) {
            return Optional.empty();
        }

        @Override
        public boolean existsById(Long aLong) {
            return false;
        }

        @Override
        public void flush() {

        }

        @Override
        public <S extends User> S saveAndFlush(S s) {
            return null;
        }

        @Override
        public void deleteInBatch(Iterable<User> iterable) {

        }

        @Override
        public void deleteAllInBatch() {

        }

        @Override
        public User getOne(Long aLong) {
            return null;
        }

        @Override
        public <S extends User> Optional<S> findOne(Example<S> example) {
            return Optional.empty();
        }

        @Override
        public <S extends User> List<S> findAll(Example<S> example) {
            return null;
        }

        @Override
        public <S extends User> List<S> findAll(Example<S> example, Sort sort) {
            return null;
        }

        @Override
        public <S extends User> Page<S> findAll(Example<S> example, Pageable pageable) {
            return null;
        }

        @Override
        public <S extends User> long count(Example<S> example) {
            return 0;
        }

        @Override
        public <S extends User> boolean exists(Example<S> example) {
            return false;
        }
    }
}

A very simple JUnit5 test

 A very simple JUnit test would be a case where we are testing a method or a class that has no dependency on any other class.

For example below is a simple calculator class that calculates sum of two numbers.

To write a unit test for this method, we simply call the add method and verify the response.

This test does not require any use of Mockito framework and can be created by using just the JUnit framework.

How to pass list of parameters using Spring Feign

We can use Spring Feign to connect to external APIs. Feign makes is very easy to connect to external APIs by providing a declarative approach and encapsulating lots of connection logic.

In this article we will discuss about how we can pass a list of values as a URL Query parameter to an api.

A webservice URL can accept a list as a parameter in one of the below two formats.

1. Repeated parameter name

/search/findByIdIn?ids=1&ids=2&ids=3


2. Comma Separated Values

/search/findByIdIn?ids=1,2,3

 

In general case, an API coded in one of the above formats can not accept parameters in the other format. As a consumer of these APIs we can not control the format used by the API. Feign provides simple solutions to choose between these types.

1. Repeated parameter name

To pass a list as repeated Query parameters, simply define the Feign methods to accept parameter as a List object. 
Example


2. Comma Separated Values

To pass a list as comma separated values in URL query parameter, we need to define the parameter as an array in our Feign client.

The feign client will create appropriate URL format based on the parameter type.