web-dev-qa-db-ja.com

Mockitoを使用してモックのすべての呼び出しを表示する方法

失敗しているユニットテストがありますが、その理由はわかりません。テスト対象のシステムで発生するモックのすべての呼び出しを確認できるようにしたいと思います。これは、すべてのテストで常に必要な動作ではなく、単に何が問題なのかを理解するためにすばやく調整する必要があるテストのためです。

ただし、ハックのようなものです。 Thread.currentThread().getStackTrace()を使用せずにMockitoでネイティブにこれを行うことは可能ですか?

スタックトレースにはMockitoによって内部的に使用される他のすべての呼び出しが含まれるため、これは推奨されません。

32
durron597

この機能はMockito 1.9.5以降に組み込まれています。使うだけ

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

Mockito _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(); 
-> at Foo.doThat()(Foo.Java:15 )
-スタブ-> at FooTest.doThat(FooTest.Java:18)

出力に参照行があるクラスは、ソースコード/テストクラスへのリンクであることに注意してください。とても実用的です。

3
davidxxx

doesThread.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;
            }
        }
    }
}
0
durron597