2012-11-13 1 views
16

を可変引数:フォース単一の引数には二つの方法(mockitoから取られた)でJavaクラスを考える

OngoingStubbing<T> thenReturn(T value); 

OngoingStubbing<T> thenReturn(T value, T... values); 

私は

....thenReturn("something") 

とスカラ座から起動する場合、私はエラーを取得:

Description Resource Path Location Type 
ambiguous reference to overloaded definition, both method thenReturn in trait OngoingStubbing of type (x$1: java.lang.Object, x$2: <repeated...>[java.lang.Object])org.mockito.stubbing.OngoingStubbing[java.lang.Object] and method thenReturn in trait OngoingStubbing of type (x$1: java.lang.Object)org.mockito.stubbing.OngoingStubbing[java.lang.Object] match argument types (java.lang.String) 

これを修正する方法を理解できません。

答えて

12

これらの回答はすべて間違った質問です。違いは微妙ですが、これはlinked ticketと同じ問題ではありません。それは非可変的な体操を非可変的な方法と呼ぶことを必要とする。このためには、次のようにすれば十分です。

thenReturn[String]("something") 

または、何らかの理由でこれを実行したくない場合は、タイプエイリアスとキャストは必要ありません。構造タイプの帰属を直接使用することができます。一つの方法は、より具体的であるが、scalacは把握されません -

(this: { def thenReturn[T](s: T): OngoingStubbing[T] }).thenReturn("something") 

ここでの問題は、過負荷状態にし、多型の交差点で推論を入力しています。 SI-2991の問題は、オーバーロードとタプル変換の間の相互作用による本質的なあいまいであり、どちらもより具体的ではありません。

+1

問題は、あなたがjava.lang.Object(別名AnyRef)を返すメソッドをスタブしているときに、Scalaに惑わされてしまうことです。 –

+0

私はあなたがオブジェクトではないAnyValを意味すると思います –

1

回避策は非常に簡単です:

OngoingStubbing<T> thenReturn(T value); 

OngoingStubbing<T> thenReturn(T value1, T valu2, T... values); 

全く機能「可変引数が非空であってはならない」があります。

+0

基本となるライブラリを変更することはできません。メソッドの例は、mockitoから取ったものです。 – monkjack

+0

Yoは、基礎となるライブラリをラップするか、常に2番目のメソッドを呼び出すことができます。 Alexeyによって他の答えで説明されているように。 – Nicolas

9

可変引数バージョンを呼び出すことは許容される場合は、

thenReturn("something", Nil: _*) 

は今、可変引数なしでメソッドを呼び出す方法を考えることはできません。

+0

これは私のケースでは私の場合doReturn(false、Nil:_ *)は、私はあなたの戻り値がAnyVal(Javaオブジェクトに変換されない)まで、第2のelipsisパラメータ –

16

これはよく知られているScala-Javaの相互運用性の問題ですが、残念ながらFAQにはありません。ここにはScala ticket describing the problemがあります。基本的に、両方のメソッドは単一の引数を与えるときに適用でき、Scalaコンパイラは現在、どちらが「より具体的」であるかを決定するヒューリスティックを持っていません。 Alexey Romanov's approach to always use the varargs versionは良い回避策です:

thenReturn("something", Nil: _*) 

question running into a similar problem with JCommanderもあります。そこでの答えの1つは、構造型を使用した巧妙な回避策です。このアプローチでは、場面の裏側で反射を使用するため、その方向へ進むことを望むかもしれません。あなたのユースケースの場合、それは次のようになります。

type useSingleArgVersion = { def thenReturn(value: AnyRef): OngoingStubbing } 
(...).asInstanceOf[useSingleArgVersion].thenReturn("something") 

最後に、similar question running into a similar problem with mokitoがあります。これは実際には回避策を提供するものではありませんが、この問題が発生した理由に興味がある場合は、少し詳しく説明します。

+0

のAnyRef要件) –

0

私はスティーブのソリューションを試してみましたが、含めた巨大なコンパイラエラーました:持ったときに他の人がこの質問を見つけるだろうと仮定

thenReturn("something", Seq.empty[Object]: _*) 
0

:私はそれのようなもので動作させることができました

scala.tools.nsc.symtab.Types$TypeError: type mismatch; 
found : scala.reflect.Manifest[Nothing] 
required: scala.reflect.ClassManifest[B] 
Note: Nothing <: B, but trait ClassManifest is invariant in type T. 
You may wish to investigate a wildcard type such as `_ <: B`. (SLS 3.2.10) 

overloaded method value thenReturn with alternativesエラー、解決策も共有したいと思います。

代わりの

when(field.getValue(isA(classOf[Record]))).thenReturn(value)

私は私の場合にはdisambiguityを解決

doReturn(value).when(field).getValue(isA(classOf[Record]))

を使用しています。

関連する問題