Mockito Verifying Timeouts

Introduction

In this chapter, we will learn about verifying timeouts using Mockito. Verifying timeouts is useful when you need to ensure that a method invocation happens within a certain time frame. This can be particularly important in applications where timely execution of tasks is crucial, such as in real-time systems or when dealing with asynchronous code.

What is Verifying Timeouts?

Verifying timeouts involves checking that a method call occurs within a specified time limit. Mockito provides a timeout method to help you achieve this, allowing you to specify the maximum time in milliseconds that the verification should wait for the method call to occur.

Example: AsyncService Class and AsyncServiceTest Class

Class Under Test: AsyncService

public class AsyncService {
    private final NotificationService notificationService;

    public AsyncService(NotificationService notificationService) {
        this.notificationService = notificationService;
    }

    public void processAsync() {
        new Thread(() -> {
            try {
                Thread.sleep(500); // Simulate delay
                notificationService.sendNotification("Processing complete");
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }).start();
    }
}

Supporting Class: NotificationService

public class NotificationService {
    public void sendNotification(String message) {
        // Send a notification
    }
}

Test Class: AsyncServiceTest

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

public class AsyncServiceTest {

    @Test
    void testProcessAsync_VerifyTimeout() {
        // Create a mock object of NotificationService
        NotificationService notificationService = mock(NotificationService.class);

        // Create an instance of AsyncService with the mock dependency
        AsyncService asyncService = new AsyncService(notificationService);

        // Call the processAsync method
        asyncService.processAsync();

        // Verify that the sendNotification method was called within 1 second
        verify(notificationService, timeout(1000)).sendNotification("Processing complete");
    }
}

Explanation

  1. Creating Mocks:
    NotificationService notificationService = mock(NotificationService.class);
    

    This line creates a mock object of the NotificationService class.

  2. Creating an Instance of AsyncService:
    AsyncService asyncService = new AsyncService(notificationService);
    

    This line creates an instance of the AsyncService class with the mock dependency.

  3. Calling the Async Method:
    asyncService.processAsync();
    

    This line calls the processAsync method on the AsyncService instance, which starts a new thread that sends a notification after a delay.

  4. Verifying Timeout:
    verify(notificationService, timeout(1000)).sendNotification("Processing complete");
    

    This line verifies that the sendNotification method was called within 1 second (1000 milliseconds) with the specified argument.

Running Tests using IntelliJ IDEA

Mockito Verifying Timeouts

Using timeout with times()

You can combine timeout() with times() to verify that a method was called a specific number of times within a given time frame.

Example: Verifying Multiple Invocations with Timeout

@Test
void testProcessAsync_VerifyTimeoutAndInvocationCount() {
    // Create a mock object of NotificationService
    NotificationService notificationService = mock(NotificationService.class);

    // Create an instance of AsyncService with the mock dependency
    AsyncService asyncService = new AsyncService(notificationService);

    // Call the processAsync method multiple times
    asyncService.processAsync();
    asyncService.processAsync();

    // Verify that the sendNotification method was called twice within 1 second
    verify(notificationService, timeout(1000).times(2)).sendNotification("Processing complete");
}

Explanation

  1. Combining timeout with times:
    verify(notificationService, timeout(1000).times(2)).sendNotification("Processing complete");
    

    This line verifies that the sendNotification method was called twice within 1 second (1000 milliseconds) with the specified argument.

Using timeout with atLeast() and atMost()

You can also combine timeout() with atLeast() and atMost() to verify that a method was called at least or at most a certain number of times within a given time frame.

Example: Verifying atLeast and atMost with Timeout

@Test
void testProcessAsync_VerifyTimeoutAtLeastAndAtMost() {
    // Create a mock object of NotificationService
    NotificationService notificationService = mock(NotificationService.class);

    // Create an instance of AsyncService with the mock dependency
    AsyncService asyncService = new AsyncService(notificationService);

    // Call the processAsync method multiple times
    asyncService.processAsync();
    asyncService.processAsync();

    // Verify that the sendNotification method was called at least once within 1 second
    verify(notificationService, timeout(1000).atLeast(1)).sendNotification("Processing complete");

    // Verify that the sendNotification method was called at most twice within 1 second
    verify(notificationService, timeout(1000).atMost(2)).sendNotification("Processing complete");
}

Explanation

  1. Combining timeout with atLeast and atMost:
    verify(notificationService, timeout(1000).atLeast(1)).sendNotification("Processing complete");
    verify(notificationService, timeout(1000).atMost(2)).sendNotification("Processing complete");
    

    These lines verify that the sendNotification method was called at least once and at most twice within 1 second (1000 milliseconds) with the specified argument.

Conclusion

Verifying timeouts using Mockito ensures that method calls occur within a specified time frame. By using the timeout() method, you can specify the maximum time in milliseconds that the verification should wait for the method call to occur. This is particularly useful for testing asynchronous code and ensuring timely execution of tasks. Combining timeout() with methods like times(), atLeast(), and atMost() allows you to create flexible and robust tests that validate the behavior of your code under various timing constraints.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top