2012-02-28 15 views

答えて

6

あなたのユースケースに基づいて、必要なインターフェイスに変換する前に元のMapへの参照を保持できるように思えます。あなただけInvocationHandlerのデリゲートを取得することにより、元のマップを再取得することができますように

しかし、(Proxyを使用して)インタフェースにMapオブジェクトを変換し、ソースコードを見て、それが見えます。

def i = 1 
def m = [ hasNext:{ true }, next:{ i++ } ] 
Iterator iter = m as Iterator 

def d = java.lang.reflect.Proxy.getInvocationHandler(iter).delegate 
assert d.is(m) 

注:私はJavaコードのユニットテストを書くためのGroovyの多くを使用し

+0

+1鮮やかな:-)私は考えなかったそれ! –

2

興味深い質問...短い答え、いいえ。長い答え、多分...あなたはこのような何かを持っていると仮定すると:

def i = 1 
Iterator iter = [ hasNext:{ true }, next:{ i++ } ] as Iterator 

は、[今すぐ、あなたがこれを行うためのメソッドを宣言することができ

println iter.take(3).collect() 

プリント[1,2,3]

を呼び出します

def mapFromInterface(Object o, Class... clz) { 
    // Get a Set of all methods across the array of classes clz 
    Set methods = clz*.methods.flatten() 
    // Then, for each of these 
    methods.collectEntries { 
    // create a map entry with the name of the method as the key 
    // and a closure which invokes the method as a value 
    [ (it.name): { Object... args -> 
        o.metaClass.pickMethod(it.name, it.parameterTypes).invoke(o, args) 
    } ] 
    } 
} 

これで、次の操作を実行できます。

def map = mapFromInterface(iter, Iterator) 

、呼び出し:

println map.next() 
println map.next() 

println mapで地図を印刷5

続い4を出力しますが得られます。しかし

[ remove:[email protected], 
    hasNext:[email protected], 
    next:[email protected] ] 

、これはマップであるとして、 thを持つ複数のメソッドを含むクラス同じ名前と異なる引数は失敗します。私はまた、最初のケースでこれを行うことがどれほど賢明であるかもわかりません...

あなたのユースケースはどのようなものですか?

+0

と頻繁に迅速としてクロージャのマップを使用します。これは、Groovyのコードの内部に依存ので、ご自身の責任で使用します私のユニットが依存しているインターフェースをスタブアウトするための汚い方法です(私が実際にインタラクションを検証することを気にしないときは、ほとんどのモックライブラリよりも簡単です)。時には私は "プロトタイプ"のスタッブされたインターフェイスを設定したいだけで、テストシナリオごとにちょっと微調整したいのですが、マップに戻すことができないとできません。 –

+0

@WillGormanあなたのユースケースについては、[plecongの答え](http://stackoverflow.com/a/9507914/6509)はおそらく私のものよりも良くて清潔です:-) –

関連する問題