Mocking with Mockito In Java

Mocking with Mockito In Java

In the Java programming language, Mockito is a popular Java mocking testing framework platform or environment. Mockito testing methods in Java are used to create mock versions of dependencies in existing program source code unit tests. Mockito helps Java developers test a user-defined custom class data type element individually without calling the actual original database, API, message queue, or other external system.

Mocking with Mockito In Java

Why use a mocking platform framework in Java?

Suppose the client service in a system environment testing method is ClientService, which is completely dependent on a ClientRepository.

public class ClientService {

private final ClientRepository repository;

public ClientService(ClientRepository repository) {

this.repository = repository;

}

public Client getClient(long id) {

return repository.findById(id);

}

}

In the above example, a unit test should not actually require a database; it only tests the ClientService.

The Mockito testing framework allows Java users to replace repositories with mocks.

Example of the basic Java Mockito testing framework.

import org.junit.jupiter.api.Test;

import org.junit.jupiter.api.extension.ExtendWith;

import org.mockito.InjectMocks;

import org.mockito.Mock;

import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;

import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)

class ClientServiceTest {

@Mock

private ClientRepository repository;

@InjectMocks

private ClientService clientService;

@Test

void shouldReturnClient() {

// Arrange

Client client = new Client(109L, “Siddhi”);

when(repository.findById(109L))

.thenReturn(client);

// Act

Client output = clientService.getClient(109L);

// Assert

assertEquals(“Siddhi”, output.getName());

}

}

What is happening in the Mockito testing above?

@Mock method

private ClientRepository repository;

This creates a mock environment for a Mockito application in the existing testing framework.

@InjectMocks method

private ClientService clientService;

This creates a ClientService and injects a mock repository into it.

when(repository.findById(109L))

.thenReturn(client);

This indicates the behavior of a mock in an existing Mockito test.

Client output = clientService.getClient(109L);

This executes the actual Mockito method that the Java user is testing.

assertEquals(“Siddhi”, output.getName());

This checks or analyzes the result of the Mockito method.

when() and thenReturn() are Mockito method functions.

Java users can configure the response of individual Mockito methods.

when(repository.findById(109L))

.thenReturn(new Client(109L, “Siddhi”));

when(repository.findById(110L))

.thenReturn(new Client(110L, “Bhavishi”));

when(repository.findById(113L))

.thenReturn(null);

Java users can also throw a custom exception.

when(repository.findById(109L))

.thenThrow(new RuntimeException(“This is a Database error”));

Verifying interactions in Mockito.

This allows Mockito to verify that any dependencies in your current program were called.

verify(repository).findById(109L);

In this, the Java user can verify the numbers called.

verify(repository, times(1)).findById(109L);

Or in this, nothing was ever called by the user.

verify(repository, never()).deleteById(anyLong());

Example of interactions in Mockito.

@Test method

void shouldFindClientById() {

Client client = new Client(109L, “Siddhi”);

when(repository.findById(109L))

.thenReturn(client);

Client output = clientService.getClient(109L);

assertEquals(“Siddhi”, output.getName());

verify(repository).findById(109L);

}

Argument matchers in Java Mockito.

Java provides its users with multiple such useful matcher function methods in the Mockito testing framework. For example, the

  • anyLong() function method,
  • anyString() function method,
  • anyInt() function method,
  • any() function method,
  • eq() function method.

Example of argument matchers.

when(repository.findById(anyLong()))

.thenReturn(client);

Now, this stub applies to any long ID. Java users can group matchers together.

when(repository.findByNameAndAge(

anyString(),

anyInt()

)).thenReturn(client);

If Java users use a matcher for one argument, they can also use matchers for other arguments.

//good method

when(repository.findByNameAndAge(

eq(“Siddhi”),

anyInt()

)).thenReturn(client);

@Mock vs. @InjectMocks methods in Java.

@Mock method

This creates a fake or mock Java mock method for testing dependency.

@Mock method

private ClientRepository repository;

@InjectMocks method

This creates a class being tested and injects its mock.

@InjectMocks method

private ClientService clientService;

This is a common pattern in the Java Mockito testing framework.

ClientServiceTest

                   |

+– ClientService ← real class mock object

                   |

+– ClientRepository ← mock method

Here, Java users typically want the user-defined custom class being tested to be the actual or original class and have its dependencies correctly mocked.

The concept of void method mocking in Java.

Here, assume we have a user-defined custom class.

public void deleteClient(long id) {

repository.deleteById(id);

}

Java clients can verify calls to it.

@Test method

void shouldDeleteClient() {

clientService.deleteClient(110L);

verify(repository).deleteById(110L);

}

Here, a Java user defines a void class method that should throw a user-defined custom class exception message.

doThrow(new RuntimeException(“This is a Database error”))

.when(repository)

.deleteById(110L);

@Spy Mocks methods concept.

In Java program source code, a @Spy method completely replaces mock behavior, while a spy method wraps a real object and allows overriding selected class behavior.

@Spy Mocks methods.

private ArrayList<String> list = new ArrayList<>();

Java users can then stub a specific class behavior.

In most common Java unit tests, when developers truly need to isolate a dependency, mocks are preferred. Excessive use of the spy method can make understanding mock unit tests a bit complex.

Detail explanation of mock vs stub vs real object.

The concepts of mock vs. stub vs. real object in a Java program are somewhat related, but both mock vs. stub vs. real object have their own distinct behavior patterns.

#Method TypePurpose of Mock Vs Stub Vs Real Class Object
1.Mock methodJava mock method used to verify interactions with a class dependency with it’s all elements
2.Stub methodStub class method used to provide predetermined class object testing responses
3.Spy methodSpy class method used to wrap a real class object, while allowing us selected behaviour to be controlled in existing class
4.Real objectReal object class object used or apply actual implementation with active program behaviour

Mock vs. Stub vs. Real Class Object Example.

when(repository.findById(109L))

.thenReturn(client);

This mock test provides a response with a pre-fixed dependency.

verify(repository).findById(109L);

This verifies an interaction method.

Common mistakes in the Java Mockito testing framework.

Mocking a custom class that the user is testing in a Java program.

Java users should generally avoid this when mocking.

@Mock method

private ClientService clientService;

If Java users are testing a ClientService, it should generally be an actual class object.

@InjectMocks method

private ClientService clientService;

Overusing mocks in Java.

  • Don’t automatically test every Java user-defined object class in a mock framework. When it involves isolating task activities, Java users should mock external or independent dependencies.
  • Apply proper testing to the implementation rather than the program behavior itself.
  • When only an observable result is reliable in the current program, Java users should avoid tests that respond to every internal class method call.

For example, this can be unnecessarily fragile.

verify(repository).findById(109L);

verify(cache).get(109L);

verify(logger).info(anyString());

verify(metrics).increment();

If these interactions are not part of the class behavior that the Java user actually needs to guarantee, they may not be included in the test.

Basic Java Program Mockito Pattern.

Java users should remember this workflow in their Java programs.

// 1. Arrange the method

when(repository.findById(109L))

.thenReturn(client);

// 2. Act the method

Client output = clientService.getClient(109L);

// 3. Assert method

assertEquals(“Siddhi”, output.getName());

// 4. Verify (when class interactions matter)

verify(repository).findById(109L);

Conclusion of Mockito in Java.

The special purpose of the Mockito unit testing framework in Java programs is to isolate source code, making unit testing method dependencies predictable. So that your tests can focus on the behavior of the class you’re actually analyzing or testing.

Leave a Reply