Как использовать Mockito, чтобы показать все вызовы на макете

У меня есть модульное тестирование, которое не проходит, и я не знаю, почему. Я хочу иметь возможность видеть все вызовы на макете, которые происходят в тестируемой системе. Это не то поведение, которое я хочу всегда для всех тестов, просто для теста, который мне нужно быстро настроить, чтобы понять, что не так.

Тем не менее, это похоже на взломать. Можно ли сделать это изначально в Mockito, не используяThread.currentThread().getStackTrace()?

Это не является предпочтительным, потому что трассировка стека включает в себя все другие вызовы, используемые внутри Mockito.

3 ответа

Решение

Эта функция встроена в Mockito 1.9.5. Просто используйте

mock(ClassToMock.class, withSettings().verboseLogging())

От мокито 1.9.5 Вы можете проверить макет с MockingDetails Mockito.mockingDetails(Object mockToInspect),

Вы можете копаться в MockingDetails свойства путем вызова: getMock(), getStubbings(), getInvocations() и так для... или просто использовать printInvocations() метод, который возвращает:

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

Например с JUnit 5:

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

@ExtendWith(MockitoExtension.class)
public class FooTest {

    Foo foo;

    @Mock
    Bar bar;

    @Test
    void doThat() throws Exception {

        Mockito.when(bar.getValue())
               .thenReturn(1000L);          

        // ACTION
        foo.doThat();

        // ASSERTION
        // ...

        // add that to debug the bar mock           
        System.out.println(mockingDetails(bar).printInvocations());
    }
}

И вы получите вывод, такой как:

[Mockito] Взаимодействия: Mock for Bar, hashCode: 962287291
 1. bar.getValue();
  -> в Foo.doThat() (Foo.java:15) 
   - заглушка -> на FooTest.doThat(FooTest.java:18)

Обратите внимание, что классы со ссылочной строкой в ​​выходных данных являются ссылками на ваш исходный код / ​​тестовый класс. Очень практично

Я смог определить метод, который использует Thread.currentThread().getStackTrace()и цикл по элементам. Это некрасиво, но это делает работу. Я надеюсь, что другой ответчик будет иметь лучший метод.

  1. Создать InvocationListenerи передайте ему имя класса тестируемой системы.
  2. Передать слушателя в Mockito.withSettings().invocationListeners()
  3. Временно измените тест, чтобы создать макет с этим MockSettings объект.

Код InvocationListener:

public static class DebugInvocationListener implements
        InvocationListener {
    private final String className;

    public DebugInvocationListener(Class<?> klass) {
        this(klass.getName());
    }

    public DebugInvocationListener(String className) {
        this.className = className;
    }

    @Override
    public void reportInvocation(MethodInvocationReport report) {
        System.out.println(report.getInvocation());
        StackTraceElement[] trace = Thread.currentThread().getStackTrace();
        for(StackTraceElement element : trace) {
            if(element.getClassName().equals(className)) {
                System.out.println(element);
                System.out.println();
                break;
            }
        }
    }
}
Другие вопросы по тегам