2010-09-17 16 views
5

मैं अपने जावा एप्लिकेशन के लिए स्केलेटेस्ट का उपयोग करके कुछ टेस्ट कोड लिखने की कोशिश कर रहा हूं। मैंने सोचा, चूंकि स्कैला के पास बहुत अधिक पठनीय वाक्यविन्यास है, इसलिए इसका परिणाम अधिक पठनीय परीक्षण कोड होगा।इस कोड को बेहतर बनाने के तरीके

अब तक, इस मैं क्या कामयाब रहे है:

 
package com.xyz 

import org.scalatest.FlatSpec 
import org.scalatest.matchers.ShouldMatchers 
import com.xyz.SecurityService 
import org.mockito.Mockito._ 
import org.scalatest.mock.MockitoSugar 
import org.mockito.Matchers._ 
import javax.servlet.jsp.tagext.Tag 

class CheckRoleTagSpec extends FlatSpec with ShouldMatchers with MockitoSugar { 

    behavior of "CheckRole tag" 

    it should "allow access when neither role nor root defined" in { 
    val securityServiceMock = mock[SecurityService] 

    val tag = new CheckRoleTag() 
    tag.setSecurityService(securityServiceMock) 

    tag.setGroup("group") 
    tag.setPortal("portal") 

    tag.setRoot(false) 
    tag.setRole(null) 

    tag.doStartTag should be(Tag.SKIP_BODY) 
    } 

} 

मैं इस कोड के साथ काफी dissapointed हूँ। यह व्यावहारिक रूप से वही बात है जिसे मुझे जावा में लिखना होगा। कृपया इसे और अधिक स्कैला-जैसी और कार्यात्मक बनाने में मेरी सहायता करें।

+0

वास्तव में क्या आप निराश? मुझे लगता है कि यह 'tag.set ...' चीज है, इसलिए आपको 'चेकरोलटाग' और शायद 'सुरक्षा सेवा' को दोबारा करना होगा। –

+0

@ michael.kebe बात यह है कि मैं स्कैला से इसका परीक्षण करने के लिए अपना जावा कोड बदलना नहीं चाहता हूं। मैं जावा को अभी भी जावा की तरह दिखाना चाहता हूं। –

+0

चेकरोलटैग के लिए एक निर्माता या वास्तविक कन्स्ट्रक्टर आपके जावा और स्कैला तरीके को बेहतर बना देगा! –

उत्तर

3

कोड के नीचे नई अज्ञात वर्ग बनाता है, लेकिन doStartTag रिटर्न की उम्मीद के रूप में परिणाम:

... 
(new CheckRoleTag{ 
    setSecurityService(mock[SecurityService]) 
    setGroup("group") 
    setPortal("portal") 
    setRoot(false) 
    setRole(null) 
} doStartTag) should be(Tag.SKIP_BODY) 
... 
+1

यह वास्तव में जाने का एक अच्छा तरीका नहीं है क्योंकि यह कक्षा का परीक्षण करने के इरादे से परीक्षण नहीं कर रहा है। यही है, यह किसी भी तर्क को छोड़ देता है जो कि सेटर्स में हो सकता है। –

3

के बाद से इस विशेष परीक्षण सिर्फ एक वस्तु जावा में कार्यान्वित पर setters के एक गुच्छा बुला रहा है, वहाँ ज़्यादा कुछ नहीं है आप इसे अधिक संक्षिप्त या कार्यात्मक या scalaish बनाने के लिए कर सकते हैं। आप

it should "allow access when neither role nor root defined" in { 
    val securityServiceMock = mock[SecurityService] 

    val tag = new CheckRoleTag() 

    locally { 
    import tag._ 
    setSecurityService(securityServiceMock) 
    setGroup("group") 
    setPortal("portal") 
    setRoot(false) 
    setRole(null) 
    } 

    tag.doStartTag should be(Tag.SKIP_BODY) 
} 

पर कुछ पुनरावृत्ति को हटा सकते हैं, मुझे यकीन नहीं है कि यह इस मामले में वास्तव में इसके लायक है या नहीं।

9

आप परीक्षण को फिर से लिखकर एक बदसूरत परीक्षण को ठीक नहीं कर सकते हैं। आप परीक्षण किए जा रहे एपीआई को फिर से डिजाइन करके इसे ठीक कर सकते हैं।

ठीक है, तकनीकी तौर पर, यह संभव अच्छा एपीआई के लिए बदसूरत परीक्षण लिखने के लिए अगर आप वास्तव में कोशिश है मुश्किल है, बहुत बुराई, बहुत, बेवकूफ, बहुत नशे में या बहुत थक गया। लेकिन एक बदसूरत परीक्षण लिखना प्रयास लेता है और प्रोग्रामर आलसी हैं, इसलिए यह बहुत संभावना है कि कोई व्यक्ति पसंद करके बदसूरत परीक्षण लिखता है। बदसूरत परीक्षण लिखना लगभग असंभव है: आप कुछ छड़ी करते हैं, आपको कुछ मिलता है, आप जांचते हैं कि आपको क्या चाहिए था। बस। वहाँ उलझन में वास्तव में कुछ भी नहीं है।

एक परीक्षण केवल एपीआई का उपयोग करता है वैसे ही एपीआई का उपयोगकर्ता इसका उपयोग करेगा। यह मूल रूप से एपीआई का सही तरीके से उपयोग करने का एक उदाहरण है, यह भी, लगभग साइड इफेक्ट के रूप में, यह जांचने के लिए होता है कि एपीआई वास्तव में लागू ठीक से लागू है। यही कारण है कि एक बदसूरत परीक्षण खराब एपीआई डिज़ाइन के लिए एक अच्छा संकेतक है, और यही कारण है कि एपीआई डिज़ाइन का परीक्षण-ड्राइविंग एक अच्छी बात है, भले ही आप टीडीडी नहीं करते हैं।

इस विशेष मामले में, मैं एपीआई को बेहतर बनाने के कुछ तरीके देख सकता हूं, हालांकि ये सुझाव आवश्यक रूप से अधूरे, उथले और सरल हैं (संभवतः गलत का उल्लेख नहीं करते हैं), क्योंकि मुझे आपके डोमेन के बारे में कुछ भी पता नहीं है:

  • बेहतर नाम: जैसे कि यह जड़ स्थापित कर रही है setRoot लग रहा है। लेकिन, जब तक false आपके पदानुक्रम की जड़ नहीं है, मुझे लगता है कि वास्तव में सेटिंग यह है कि यह टैग रूट है या नहीं। इसलिए, इसे isRoot या makeRoot या setIsRoot या ऐसा कुछ नाम दिया जाना चाहिए।
  • बेहतर डिफ़ॉल्ट: setRoot के साथ जारी है, यह मानते हुए कि मेरा अनुमान सही है और यह सेट करता है कि टैग रूट है या नहीं, तो डिफ़ॉल्ट गलत तरीका है। "रूट" की अवधारणा की परिभाषा से, केवल एक रूट हो सकता है।इसलिए, आप अपने उपयोगकर्ताओं को setRoot(false)निर्दिष्ट करने के लिए हर बार निर्दिष्ट कर सकते हैं, एक उस समय को छोड़कर जब वे वास्तव में रूट को परिभाषित कर रहे हों। गैर रूट टैग डिफ़ॉल्ट होना चाहिए, और आपको केवल पर एक टैग के लिए मजबूर होना चाहिए जो वास्तव में रूट रूट है।
  • बेहतर डिफ़ॉल्ट, भाग II: setRole(null)। गंभीरता से? आप अपने उपयोगकर्ताओं को स्पष्ट रूप से सेट करने के लिए मजबूर कर रहे हैं को अनसेट करें? क्यों न केवल डिफ़ॉल्ट को अनसेट करें? आखिरकार, परीक्षण "... जब न तो भूमिका और न ही रूट परिभाषित किया जाता है", तो उन्हें परिभाषित क्यों करें?
  • Fluent एपीआई/बिल्डर पैटर्न: यदि आप वास्तव में अवैध वस्तुओं का निर्माण (लेकिन अगले अंक देखें), कम से कम एक सुविज्ञ एपीआई या एक बिल्डर पैटर्न की तरह कुछ का उपयोग करने के लिए है।
  • केवल वैध वस्तुओं का निर्माण: लेकिन वास्तव में, वस्तुओं को हमेशा बनाए जाने पर वैध, पूर्ण और पूरी तरह से कॉन्फ़िगर किया जाना चाहिए। आपको ऑब्जेक्ट बनाने की आवश्यकता नहीं है, और फिर इसे कॉन्फ़िगर करें।

इस तरह, परीक्षण मूल रूप से हो जाता है:

package com.xyz 

import org.scalatest.FlatSpec 
import org.scalatest.matchers.ShouldMatchers 
import com.xyz.SecurityService 
import org.mockito.Mockito._ 
import org.scalatest.mock.MockitoSugar 
import org.mockito.Matchers._ 
import javax.servlet.jsp.tagext.Tag 

class CheckRoleTagSpec extends FlatSpec with ShouldMatchers with MockitoSugar { 
    behavior of "CheckRole tag" 
    it should "allow access when neither role nor root defined" in { 
    val tag = new CheckRoleTag(mock[SecurityService], "group", "portal") 

    tag.doStartTag should be(Tag.SKIP_BODY) 
    } 
} 
संबंधित मुद्दे

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