Журналирование вызовов методов в Mocks and Spies: подробное руководство

В современной разработке программного обеспечения умение эффективно тестировать код имеет решающее значение. Издевательство и слежка за объектами — обычная практика модульного тестирования, когда мы имитируем определенное поведение или отслеживаем вызовы методов. В этой статье мы рассмотрим различные методы ведения журналов для вызовов методов фиктивных и шпионских объектов. Мы предоставим примеры кода для иллюстрации каждого метода, что позволит вам реализовать ведение журнала в ваших собственных проектах.

Регистрация вызовов методов в макетах:

  1. Использование метода проверки():
    Метод проверки() позволяет нам проверить, был ли вызван определенный метод для фиктивного объекта. Объединив его с операторами журналирования, мы можем эффективно фиксировать вызовы методов. Вот пример использования платформы Mockito:

    import static org.mockito.Mockito.*;
    // Create a mock object
    List<String> mockList = mock(List.class);
    // Log and verify method invocation
    System.out.println("Invoking add() method on mockList");
    mockList.add("example");
    verify(mockList).add("example");
  2. Реализация пользовательского ведения журнала.
    Другой подход заключается во внедрении специального механизма ведения журнала, который перехватывает вызовы методов фиктивного объекта. Этого можно добиться, создав прокси-объект, который обертывает макет и регистрирует вызовы метода. Вот упрощенный пример:

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    // Create a mock object
    List<String> mockList = mock(List.class);
    // Create a proxy object with custom logging
    List<String> loggedList = (List<String>) Proxy.newProxyInstance(
       List.class.getClassLoader(),
       new Class<?>[]{List.class},
       new InvocationHandler() {
           public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
               System.out.println("Invoking method: " + method.getName());
               return method.invoke(mockList, args);
           }
       }
    );
    // Use the loggedList object instead of the mockList
    loggedList.add("example");

Регистрация вызовов методов шпионов:

  1. Использование метода doCallRealMethod():
    В Mockito шпион — это частичная имитация, где некоторые методы могут быть реальными, а другие — высмеиваемыми. Используя метод doCallRealMethod() вместе с операторами журналирования, мы можем регистрировать вызовы метода, продолжая при этом выполнять реальную логику метода. Вот пример:

    import static org.mockito.Mockito.*;
    // Create a spy object
    List<String> spyList = spy(new ArrayList<>());
    // Log and invoke the real add() method
    System.out.println("Invoking add() method on spyList");
    doCallRealMethod().when(spyList).add(anyString());
    spyList.add("example");
    // Verify the method invocation
    verify(spyList).add("example");
  2. Использование аспектно-ориентированного программирования (АОП).
    Среды АОП, такие как AspectJ, могут перехватывать вызовы методов и обеспечивать возможности ведения журнала. Создав аспект, нацеленный на шпионский объект и определяющий поведение журналирования, мы можем эффективно регистрировать вызовы методов. Вот упрощенный пример:

    import org.aspectj.lang.annotation.*;
    // Create a spy object
    List<String> spyList = spy(new ArrayList<>());
    // Define an aspect for logging method invocations
    @Aspect
    public class LoggingAspect {
       @Before("execution(* *(..)) && this(spyList)")
       public void logMethodInvocation(JoinPoint joinPoint) {
           System.out.println("Invoking method: " + joinPoint.getSignature().getName());
       }
    }
    // Use the spyList object as usual
    spyList.add("example");

Регистрация вызовов методов в моках и шпионах — это мощный метод понимания и отладки поведения кода во время тестирования. Мы исследовали различные методы достижения этой цели, в том числе использование встроенных методов проверки, реализацию пользовательских механизмов журналирования и использование инфраструктур АОП. Используя эти методы, вы можете получить ценную информацию о том, как ваш код взаимодействует с макетами и шпионскими объектами во время модульного тестирования.