Mockito eq()

Introduction

The eq() method in Mockito is used to specify that a method argument must exactly match the given value. This is particularly useful when you want to verify interactions or stub methods with specific argument values. This tutorial will demonstrate how to use the eq() method in Mockito to handle method arguments.

Maven Dependencies

To use Mockito with JUnit 5, add the following dependencies to your pom.xml file:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>4.8.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>4.8.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.9.2</version>
    <scope>test</scope>
</dependency>

Example Scenario

We will create a StudentService class that has a dependency on a StudentRepository. Our goal is to test the StudentService methods using the eq() method in Mockito to verify and stub methods with specific argument values.

StudentService and StudentRepository Classes

First, create the Student class, the StudentRepository interface, and the StudentService class.

public class Student {
    private String name;
    private String email;

    // Constructor, getters, and setters
    public Student(String name, String email) {
        this.name = name;
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

public interface StudentRepository {
    void saveStudent(Student student);
    Student findStudentByEmail(String email);
}

public class StudentService {
    private final StudentRepository studentRepository;

    public StudentService(StudentRepository studentRepository) {
        this.studentRepository = studentRepository;
    }

    public void registerStudent(String name, String email) {
        Student student = new Student(name, email);
        studentRepository.saveStudent(student);
    }

    public Student getStudentByEmail(String email) {
        return studentRepository.findStudentByEmail(email);
    }
}

JUnit 5 Test Class with Mockito

Create a test class for StudentService using JUnit 5 and Mockito.

import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(MockitoExtension.class)
public class StudentServiceTest {

    @Mock
    private StudentRepository studentRepository;

    @InjectMocks
    private StudentService studentService;

    @Test
    public void testRegisterStudent() {
        // Given
        String name = "Rajesh Kumar";
        String email = "rajesh.kumar@example.com";

        // When
        studentService.registerStudent(name, email);

        // Then
        verify(studentRepository).saveStudent(eq(new Student(name, email)));
    }

    @Test
    public void testGetStudentByEmail() {
        // Given
        String email = "deepika.sharma@example.com";
        Student student = new Student("Deepika Sharma", email);
        when(studentRepository.findStudentByEmail(eq(email))).thenReturn(student);

        // When
        Student result = studentService.getStudentByEmail(email);

        // Then
        assertNotNull(result);
        assertEquals("Deepika Sharma", result.getName());
        assertEquals(email, result.getEmail());
        verify(studentRepository).findStudentByEmail(eq(email));
    }
}

Explanation

  1. Creating Mocks with @Mock:

    • The @Mock annotation creates a mock instance of the StudentRepository interface. This mock instance can be used to simulate the behavior of the StudentRepository in a controlled way.
  2. Injecting Mocks with @InjectMocks:

    • The @InjectMocks annotation injects the mock StudentRepository into the StudentService instance to provide a controlled test environment. This allows the StudentService methods to be tested in isolation from the actual StudentRepository implementation.
  3. Verifying Interactions with eq():

    • The verify(studentRepository).saveStudent(eq(new Student(name, email))); method checks if the saveStudent method was called on the StudentRepository with a Student object that matches the specified name and email. This ensures that the registerStudent method of the StudentService class interacts with the StudentRepository correctly with the exact Student object passed.
    • The verify(studentRepository).findStudentByEmail(eq(email)); method checks if the findStudentByEmail method was called on the StudentRepository with the exact email. This ensures that the getStudentByEmail method of the StudentService class interacts with the StudentRepository correctly with the exact email passed.
  4. Stubbing Methods with eq():

    • The when(studentRepository.findStudentByEmail(eq(email))).thenReturn(student); method configures the mock StudentRepository to return a specific Student object when the findStudentByEmail method is called with the exact email value. This allows the getStudentByEmail method of the StudentService class to be tested with controlled behavior from the StudentRepository.

Additional Scenarios

Scenario: Verifying Method Called with Specific Argument

In this scenario, we will demonstrate how to verify that a method was called with a specific argument using the eq() method.

@Test
public void testSaveStudentWithSpecificArgument() {
    // Given
    String name = "Anita Singh";
    String email = "anita.singh@example.com";
    Student student = new Student(name, email);

    // When
    studentService.registerStudent(name, email);

    // Then
    verify(studentRepository).saveStudent(eq(student));
}

Scenario: Stubbing Method with Specific Argument

In this scenario, we will demonstrate how to stub a method with a specific argument using the eq() method.

@Test
public void testFindStudentByEmailWithSpecificArgument() {
    // Given
    String email = "ajay.patel@example.com";
    Student student = new Student("Ajay Patel", email);
    when(studentRepository.findStudentByEmail(eq(email))).thenReturn(student);

    // When
    Student result = studentService.getStudentByEmail(email);

    // Then
    assertNotNull(result);
    assertEquals("Ajay Patel", result.getName());
    assertEquals(email, result.getEmail());
    verify(studentRepository).findStudentByEmail(eq(email));
}

Conclusion

The eq() method in Mockito simplifies the verification and stubbing of method calls on mock objects with specific argument values for unit testing. By using eq(), you can ensure that your code interacts with its dependencies as expected with the exact values. This step-by-step guide demonstrated how to effectively use the eq() method in your unit tests, covering different scenarios to ensure comprehensive testing of the StudentService class.

Related Mockito Methods

Mockito mock()
Mockito spy()
Mockito when()
Mockito thenThrow()
Mockito verify()
Mockito times()
Mockito never()
Mockito any()
Mockito eq()
Mockito inOrder()
Mockito doReturn()
Mockito doThrow()
Mockito doAnswer()
Mockito timeout()
Mockito ArgumentMatchers

Comments