In this section, we will explore how to verify interactions with mocks using Mockito in JUnit. Verifying interactions is crucial to ensure that your code behaves as expected, especially when dealing with dependencies and side effects.

Key Concepts

  1. Mocking: Creating a mock object to simulate the behavior of real objects.
  2. Verification: Checking if certain methods were called on the mock object with the expected arguments.

Why Verify Interactions?

Verifying interactions helps to:

  • Ensure that the correct methods are called.
  • Validate the sequence of method calls.
  • Confirm that no unexpected interactions occur.

Setting Up Mockito

Before we dive into verifying interactions, ensure you have Mockito set up in your project. Add the following dependencies to your pom.xml if you are using Maven:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>3.11.2</version>
    <scope>test</scope>
</dependency>

Basic Verification

Example

Let's start with a simple example. Suppose we have a Calculator class with a method add:

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
}

We want to verify that the add method is called with specific arguments.

Test Case

import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

public class CalculatorTest {

    @Test
    public void testAddMethodCalled() {
        // Create a mock of Calculator
        Calculator calculator = mock(Calculator.class);

        // Use the mock object
        calculator.add(10, 20);

        // Verify that the add method was called with arguments 10 and 20
        verify(calculator).add(10, 20);
    }
}

Explanation

  1. Creating a Mock: Calculator calculator = mock(Calculator.class);
    • This creates a mock object of the Calculator class.
  2. Using the Mock: calculator.add(10, 20);
    • We call the add method on the mock object.
  3. Verifying the Interaction: verify(calculator).add(10, 20);
    • This verifies that the add method was called with the arguments 10 and 20.

Advanced Verification

Verifying Call Count

You can also verify how many times a method was called:

verify(calculator, times(1)).add(10, 20);

Verifying No Interactions

To ensure that no interactions have occurred with the mock:

verifyNoInteractions(calculator);

Verifying No More Interactions

To verify that no other interactions have occurred after the specified calls:

verify(calculator).add(10, 20);
verifyNoMoreInteractions(calculator);

Verifying in Order

To verify that methods were called in a specific order:

import static org.mockito.Mockito.*;
import org.mockito.InOrder;
import org.junit.jupiter.api.Test;

public class CalculatorTest {

    @Test
    public void testMethodCallOrder() {
        Calculator calculator = mock(Calculator.class);

        // Use the mock object
        calculator.add(10, 20);
        calculator.add(30, 40);

        // Create an InOrder verifier for the mock
        InOrder inOrder = inOrder(calculator);

        // Verify the order of method calls
        inOrder.verify(calculator).add(10, 20);
        inOrder.verify(calculator).add(30, 40);
    }
}

Practical Exercise

Exercise

  1. Create a UserService class with a method createUser(String username).
  2. Create a test case to verify that the createUser method is called with the argument "john_doe".

Solution

public class UserService {
    public void createUser(String username) {
        // Logic to create a user
    }
}

import static org.mockito.Mockito.*;
import org.junit.jupiter.api.Test;

public class UserServiceTest {

    @Test
    public void testCreateUserCalled() {
        // Create a mock of UserService
        UserService userService = mock(UserService.class);

        // Use the mock object
        userService.createUser("john_doe");

        // Verify that the createUser method was called with argument "john_doe"
        verify(userService).createUser("john_doe");
    }
}

Common Mistakes and Tips

  • Forgetting to Use verify: Always use verify to check interactions.
  • Incorrect Argument Matching: Ensure the arguments in verify match exactly with the method call.
  • Overusing Verification: Verify only necessary interactions to keep tests maintainable.

Conclusion

In this section, we learned how to verify interactions with mocks using Mockito in JUnit. We covered basic verification, advanced verification techniques, and common mistakes. Verifying interactions is a powerful tool to ensure your code behaves as expected, especially when dealing with dependencies. In the next module, we will explore advanced JUnit features such as timeouts and exception testing.

© Copyright 2024. All rights reserved