2011-10-23 12 views
6

मैंने कल स्कैला सीखना शुरू किया, इसलिए मैं इसके लिए बहुत नया हूं। एक नई भाषा सीखते समय मुझे एक चीज करना पसंद है जो माइक्रो-टीडीडी लिब बनाने की कोशिश कर रहा है।स्कैला - मैं "assertThrows" विधि कैसे करूं?

यह मैं अब तक क्या मिला है:

def assert(condition: Boolean, message: String) { 
    if(!condition){ throw new AssertionError(message) } 
} 

def assertThrows[E](f: => Unit) { 
    try { 
    f 
    } catch { 
    case e: E => { return } 
    case _: Exception => { } 
    } 
    throw new AssertionError("Expected error of type " + classOf[E]) 
} 

कोड assert के लिए काम करता है ठीक है, लेकिन मैं assertThrows के साथ दो समस्याएं आ रही हैं।

  • ऐसा लगता है कि मैं अंतिम पंक्ति पर E उपयोग नहीं कर सकते। कोई फर्क नहीं पड़ता कि मैं क्या करता हूं, मुझे class type expected but E found error मिलता है।
  • अगर मैं अंतिम पंक्ति से ई निकाल सकते हैं (यह throw new AssertionError("error expected") द्वारा की जगह, उदाहरण के लिए) मैं इस मिल: warning: abstract type E in type pattern is unchecked since it is eliminated by erasure

मुझे लगता है कि दोनों समस्याओं मैं आ रही है जिस तरह से स्काला के साथ संबंधित हैं (और शायद जावा) अमूर्त प्रकारों से संबंधित है, और वे कैसे किए जाते हैं।

मैं अपने assertThrows ठीक कर सकते हैं?

बोनस अंक: जिस तरह से मैं एक "ब्लॉक प्रकार" (f: => Unit) सही निर्दिष्ट करने कर रहा हूँ है?

+1

एक प्रश्न जो मैंने बहुत पहले नहीं किया था, मदद की जा सकती है: http://stackoverflow.com/questions/7699709/scala-expected-exception-snippet –

उत्तर

8

जावा वर्चुअल मशीन टाइप एरर के माध्यम से जेनरिक लागू करता है, इसलिए विधि निकाय के अंदर JVM वास्तव में ई के प्रकार के बारे में कुछ भी नहीं जानता है, इसलिए यह AssertThrows विधि आपके इच्छित तरीके से काम नहीं कर सकती है। आप परोक्ष अपने अपवाद वर्ग के लिए एक प्रकट पारित करने के लिए है, इसलिए की तरह की जरूरत है:

def assertThrows[E](f: => Unit)(implicit eType:ClassManifest[E]) { 

तो फिर तुम यह शरीर में उपयोग करने के अपवाद को पकड़ने के लिए कर सकते हैं या तो की तरह वर्ग के नाम मिलता है:

try { 
    f 
    } catch { 
    case e: Exception => 
     if (eType.erasure.isAssignableFrom(e.getClass)) 
     return; 
    } 
    throw new AssertionError("Expected error of type " + eType.erasure.getName) 
} 

धन्यवाद the Spring framework's AssertThrows class पर मुझे यह दिखाने के लिए कि यह कैसे करें।

class AssertException(msg: String) extends Exception(msg: String) 

def assertThrows[E](f: => Unit)(implicit eType:ClassManifest[E]) { 
    try{ 
    f 
    } catch { 
    case e: Exception => 
    if(eType.erasure.isAssignableFrom(e.getClass)) { return } 
    } 
    throw new AssertException("Expected error of type " + eType.erasure.getName) 
} 

/* examples of usage */ 

assertThrows[NullPointerException]{ throw new NullPointerException() } // ok 
assertThrows[AssertException] { assertThrows[Exception]{ } } // ok! 

धन्यवाद एक बहुत:

+0

आपके उत्तर के लिए धन्यवाद। क्या आप उपयोग का एक उदाहरण शामिल कर सकते हैं? मैं इसे काम नहीं कर पा रहा हूं। – kikito

+0

कभी नहीं, मुझे यह काम मिल गया (एक जवाब जोड़ा गया)। मैं आपके उत्तर में एक छोटा टाइपो संपादित कर रहा हूं और इसे सही के रूप में चिह्नित कर रहा हूं। – kikito

0

मैं इस बात केन के जवाब के लिए धन्यवाद काम कर मिल गया है!

+0

वास्तव में कमाल !! –

संबंधित मुद्दे