2014-12-12 3 views
11

निम्नलिखित को देखते हुए, मैं कैसे processMessage() नकली स्पॉक का उपयोग कर, ताकि मैं जांच कर सकते हैं कि processBulkMessage() कॉल processMessage() एन बार, जहां n एक BulkMessage भीतर संदेशों की संख्या है?Grails/स्पॉक: कैसे वर्ग के भीतर एक तरीका है, जहां विधि वर्ग के भीतर ही से कहा जाता है उपहास करने के लिए?

class BulkMessage { 
    List messages 
} 

class MyService { 

    def processBulkMessage(BulkMessage msg) { 
     msg.messages.each {subMsg-> 
      processMessage(subMsg) 
     } 
    } 

    def processMessage(Message message) { 

    } 
} 

उत्तर

5

आप spies और आंशिक mocks उपयोग कर सकते हैं (स्पॉक 0.7 या नए की आवश्यकता है)।

एक जासूस बनाने के बाद, आप कॉलर और असली जासूस अंतर्निहित वस्तु के बीच बातचीत को सुन सकते हैं:

def subscriber = Spy(SubscriberImpl, constructorArgs: ["Fred"]) 
subscriber.receive(_) >> "ok" 

कभी कभी, यह दोनों कुछ कोड निष्पादित करने के लिए वांछनीय है और वास्तविक विधि प्रतिनिधि:

subscriber.receive(_) >> { String message -> callRealMethod(); message.size() > 3 ? "ok" : "fail" } 
1

यह स्पॉक में निर्मित एपीआई (यकीन नहीं कैसे आंशिक रूप से एक वस्तु उपहास करने के लिए) मजाक का उपयोग नहीं करता है, लेकिन इस चाल करना चाहिए:

class FooSpec extends Specification { 

    void "Test message processing"() { 
     given: "A Bulk Message" 
     BulkMessage bulk = new BulkMessage(messages: ['a', 'b', 'c']) 

     when: "Service is called" 
     def processMessageCount = 0 
     MyService.metaClass.processMessage { message -> processMessageCount++ } 
     def service = new MyService() 
     service.processBulkMessage(bulk) 

     then: "Each message is processed separately" 
     processMessageCount == bulk.messages.size() 
    } 
} 
2

मैं n मेरी राय यह एक अच्छी तरह से डिजाइन समाधान नहीं है। टेस्ट और डिज़ाइन चलने वाले हाथ - मैं this की बेहतर जांच करने की सलाह देता हूं। यदि किसी ऑब्जेक्ट पर किसी अन्य ऑब्जेक्ट पर परीक्षण करने की आवश्यकता है या नहीं, तो ऐसा लगता है कि इसे अन्य ऑब्जेक्ट में अलग-अलग ज़िम्मेदारी के साथ ले जाया जाना चाहिए।

यहाँ कैसे मैं यह कर जाएगा। मुझे पता है कि कैसे दृश्यता groovy में काम करता है तो टिप्पणियों को ध्यान में रखो।

@Grab('org.spockframework:spock-core:0.7-groovy-2.0') 
@Grab('cglib:cglib-nodep:3.1') 

import spock.lang.* 

class MessageServiceSpec extends Specification { 

    def 'test'() { 
     given: 
     def service = new MessageService() 
     def sender = GroovyMock(MessageSender) 

     and: 
     service.sender = sender 

     when: 
     service.sendMessages(['1','2','3']) 

     then: 
     3 * sender.sendMessage(_) 
    } 
} 
class MessageSender { //package access - low level 
    def sendMessage(String message) { 
     //whatever 
    } 
} 

class MessageService { 

    MessageSender sender //package access - low level 

    def sendMessages(Iterable<String> messages) { 
     messages.each { m -> sender.sendMessage(m) } 
    } 
} 
+0

धन्यवाद बहुत बहुत - मैं सिर्फ इस पर दोबारा गौर किया है और डिजाइन के बारे में बहुत कुछ सीखा है के बाद से मैं सवाल पूछा था। अब मैं आपसे सहमत हूं कि बेहतर डिज़ाइन एक थोक मैसेज प्रोसेसिंग सेवा और एक व्यक्तिगत मैसेज प्रोसेसिंग सेवा होगी। इसलिए एक नकली के साथ परीक्षण छोटा है। – John

1

स्पॉक में जावा स्प्रिंग लोगों परीक्षण के लिए:

constructorArgs जाना है, लेकिन निर्माता इंजेक्शन का उपयोग तरीका है। जासूस() आपको सीधे ऑटोवायर फ़ील्ड सेट करने नहीं देगा।

// **Java Spring** 
class A { 
    private ARepository aRepository; 

    @Autowire 
    public A(aRepository aRepository){ 
     this.aRepository = aRepository; 
    } 

    public String getOne(String id) { 
     tryStubMe(id) // STUBBED. WILL RETURN "XXX" 
     ... 
    } 

    public String tryStubMe(String id) { 
     return aRepository.findOne(id) 
    } 

    public void tryStubVoid(String id) { 
     aRepository.findOne(id) 
    } 
} 

// **Groovy Spock** 
class ATest extends Specification { 

    def 'lets stub that sucker' { 
     setup: 
      ARepository aRepository = Mock() 
      A a = Spy(A, constructorArgs: [aRepository]) 
     when: 
      a.getOne() 
     then: 
      // Stub tryStubMe() on a spy 
      // Make it return "XXX" 
      // Verify it was called once 
      1 * a.tryStubMe("1") >> "XXX" 
    } 
}  

स्पॉक - छोटा करते जासूस पर शून्य विधि आपत्ति

// **Groovy Spock** 
class ATest extends Specification { 

    def 'lets stub that sucker' { 
     setup: 
      ARepository aRepository = Mock() 
      A a = Spy(A, constructorArgs: [aRepository]) { 
       1 * tryStubVoid(_) >> {} 
      } 
     when: 
      ... 
     then: 
      ... 
    } 
} 
संबंधित मुद्दे

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