“静的反射” Javaで動作しますか? (例:mockitoまたはeasymock)
-
06-07-2019 - |
質問
私は.NETの男です。主にC#でコーディングします。
C#3.0以降、ラムダ式と式ツリーを活用して、静的反射。たとえば、次のスニペットに GetMethodName
を実装して、パラメータで渡されたメソッドの名前を返すことができます。
string methodName = GetMethodName( o => o.DoSomething());
Console.WriteLine(methodName); // displays "DoSomething"
今、Javaの世界でMockitoサンプル(またはEasyMockサンプル)を見ると、次のように見えます:
LinkedList mockedList = mock(LinkedList.class);
when(mockedList.get(0)).thenReturn("first");
どのように機能しますか?
when
メソッドはどのように機能しますか? mockedList.get(0)
は、値としてではなくパラメーターとして0が渡された getメソッドの呼び出しとしてどのように解釈されますか?
解決
モックライブラリは通常、式ツリーでは機能しません。適切なインターフェイスを実装し、メソッドの呼び出しに応答する型を作成します。これは、それらを記録するか、検証して事前にプログラムされた応答を返すことによって行われます。これは通常、プロキシ(例: RealProxyを使用して行われます。 .NETの、プロキシ Java)または動的コード生成を使用します。
EasyMockの場合、ソースコードでわかるように、 Proxy
(とにかくインターフェイス用)を使用します。 org.easymock.internal.JavaProxyFactory
。
他のヒント
Javaモックライブラリは通常、次のように機能します。
モックを作成すると、実際のプロキシが作成され(インターフェイスまたはサブクラスから)、インスタンスは「記録モード」になります。これは、後続の呼び出しが記録されることを意味します(メソッド名、パラメーター、期待される戻り値)。記録モードのプロキシは、実際には呼び出しを記録するだけであることに注意してください。反映自体はありません。メタデータの検出などはありません。もちろん、これらのライブラリはいくつかのトリックを実行します(スレッドローカル変数に呼び出しを格納してvoidを返すメソッドを処理するなど)が、考え方は変わりません。
次に、「リプレイモード」がが開始されると、モックインスタンスは呼び出しのリスト(メソッド+パラメーター&戻り値)からの期待を単にチェックします。
私はmockitoやeasymockを使ったことは一度もありませんが、呼び出しがあなたが思っているようなことをしないと思います。 mockedList.get(0)
を特別な方法で解釈しません。メソッド get
は通常 mockedList
オブジェクトで実行され、その result は when
に渡されます。
mockedList.get(0)
はメソッド呼び出しの構文であり、まさにそれを行います。その方法が何をするかは明確ではありません。 mockedList
のランタイムタイプは、 mock
メソッドによって返される LinkedList
のサブクラスになります。