2012-11-13 5 views
16

दो विधियों के साथ एक जावा वर्ग (mockito से लिया गया) को देखते हुए:फोर्स एकल तर्क varargs

: मैं कोई त्रुटि मिलती है

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 में से एक जैसा ही मुद्दा नहीं है। गैर-varargs विधि को कॉल करने के लिए उसमें अनुचित जिमनास्टिक की आवश्यकता होती है। इस के लिए, निम्नलिखित पर्याप्त है।

thenReturn[String]("something") 

या, यदि आप किसी कारण से ऐसा नहीं करना चाहते हैं, तो आपको उपनाम और कलाकार के प्रकार की आवश्यकता नहीं है। आप संरचनात्मक प्रकार के शिलालेख का सीधे उपयोग कर सकते हैं।

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

यहां मुद्दा अधिक भार और बहुरूपता के चौराहे पर अनुमान टाइप है - एक विधि अधिक विशिष्ट है, लेकिन scalac जो यह पता लगाने नहीं करता है। एसआई -29 9 1 में मुद्दा ओवरलोडिंग और टुपल रूपांतरण के बीच एक बातचीत के कारण वास्तविक अस्पष्टता है - न तो अधिक विशिष्ट है।

+1

समस्या यह है कि जब आप एक विधि को दबा रहे हैं जो java.lang.Object (उर्फ AnyRef) देता है और फिर आप स्कैला द्वारा खराब हो जाते हैं। –

+0

मुझे लगता है कि आपका मतलब कोई भी वैल्यू है जो ऑब्जेक्ट नहीं है –

1

वैकल्पिक हल काफी आसान है:

OngoingStubbing<T> thenReturn(T value); 

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

कोई सुविधा "varargs गैर रिक्त होना ही चाहिए" नहीं है।

+0

मैं अंतर्निहित पुस्तकालय को नहीं बदल सकता। उदाहरण विधियों को मॉकिटो से लिया जाता है। – monkjack

+0

यो या तो अंतर्निहित लाइब्रेरी को लपेट सकता है या हमेशा दूसरी विधि को कॉल कर सकता है। जैसा कि दूसरे जवाब में एलेक्सी द्वारा समझाया गया है। – Nicolas

9

तो vararg संस्करण बुला स्वीकार्य है,

thenReturn("something", Nil: _*) 

एक तरह से बिना अभी varargs विधि कॉल करने के बारे में सोच नहीं सकता।

+0

यह मेरे मामले में मेरे लिए काम करता है DoReturn (झूठी, शून्य: _ *) मुझे दूसरी elipsis param –

16

यह ज्ञात स्कैला-जावा इंटरऑपरेबिलिटी समस्या है, हालांकि दुर्भाग्यवश यह FAQ में नहीं है। यहां Scala ticket describing the problem है। अनिवार्य रूप से, जब आप एक तर्क देते हैं तो दोनों विधियां लागू होती हैं, और स्कैला कंपाइलर के पास वर्तमान में यह तय करने के लिए कोई ह्युरिस्टिक नहीं है कि कौन सा "अधिक विशिष्ट" है।

thenReturn("something", Nil: _*) 

भी एक question running into a similar problem with JCommander है: Alexey Romanov's approach to always use the varargs version एक अच्छा समाधान नहीं है। उत्तर में से एक संरचनात्मक प्रकारों का उपयोग कर एक चालाक कामकाज देता है। यह दृष्टिकोण दृश्यों के पीछे प्रतिबिंब का उपयोग करेगा, ताकि आप उस दिशा में जाना चाहें या नहीं। आपके उपयोग के मामले के लिए, यह कुछ इस प्रकार दिखाई तरह होगा:

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

अंत में, वहाँ है एक similar question running into a similar problem with mokito। यह वास्तव में कोई कामकाज प्रदान नहीं करता है, लेकिन यदि आप इस कारण में रूचि रखते हैं तो यह समस्या को और अधिक विस्तार से बताता है।

+0

की किसी भी आरईएफ आवश्यकता को पार करने की अनुमति देता है जब तक कि आपकी वापसी एक AnyVal (जो जावा ऑब्जेक्ट में अनुवाद नहीं करती है)) –

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) 

मैं इसे की तरह कुछ के साथ काम कर रहा था:

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

मान लिया जाये कि दूसरों जब होने इस सवाल मिलेगा overloaded method value thenReturn with alternatives त्रुटि, मैं अपना समाधान भी साझा करना चाहता हूं।

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

के बजाय

मैं

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

जो मेरे मामले में disambiguity निराकरण का उपयोग करें।