2009-01-23 6 views
12

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

उत्तर

5

अभिनेता-शैली संदेश गुजरने की गतिशील प्रकृति के कारण, कलाकारों का मज़ाक उड़ाते हुए आमतौर पर कोई परेशानी नहीं होती है। बस एक अभिनेता बनाएं जो वांछित संदेश प्राप्त करता है और आप घर मुक्त हैं। आपको निश्चित रूप से यह सुनिश्चित करने की ज़रूरत होगी कि यह नकली अभिनेता वह है जिस पर संदेश पारित किए जाते हैं, लेकिन जब तक आप जिस अभिनेता का परीक्षण करने का प्रयास कर रहे हैं, वह तब तक कोई समस्या नहीं होनी चाहिए जब reentrant है।

3

मुझे लगता है कि जटिलता एक जोड़े कारकों पर निर्भर करता ...

  1. अभिनेता कैसे स्टेटफुल है?

यह एक idempotent समारोह की तरह बर्ताव करता है, तो केवल अतुल्यकालिक, तो यह एक अभिनेता के एक संदेश भेजता है और उसके बाद की जाँच करता है कि यह उम्मीद संदेशों वापस प्राप्त करता है कि मजाक का एक सरल बात होना चाहिए। यदि आप फांसी के बजाय उचित समय के भीतर प्रतिक्रिया दे सकते हैं तो आप शायद नकली अभिनेता पर प्रतिक्रिया/प्राप्त करने के लिए उपयोग करना चाहते हैं।

हालांकि अगर संदेश एक दूसरे से स्वतंत्र नहीं हैं, तो आपको संदेशों और अपेक्षित परिणामों के विभिन्न अनुक्रमों के साथ इसका परीक्षण करना चाहिए।

  1. अभिनेता के साथ कितने कलाकारों का परीक्षण किया जाएगा?

यदि किसी अभिनेता से कई अन्य लोगों के साथ बातचीत करने की उम्मीद है, और यह राज्यपूर्ण है, तो संदेशों को भेजने/प्राप्त करने वाले कई कलाकारों के साथ इसका परीक्षण किया जाना चाहिए। चूंकि आपके पास शायद उस आदेश की कोई गारंटी नहीं है जिसमें संदेश आएंगे, आपको यह सुनिश्चित करना चाहिए कि ऑर्डर करने वाले आदेशों को अनुमति दें या जिसमें कलाकार संदेश भेजते हैं या संदेशों को उत्पन्न करने वाले कलाकारों में यादृच्छिक विराम प्रस्तुत करते हैं और परीक्षण को कई बार चलाते हैं।

मुझे अभिनेताओं की जांच के लिए किसी भी पूर्वनिर्धारित ढांचे के बारे में पता नहीं है, लेकिन आप शायद प्रेरणा के लिए एर्लांग को देख सकते हैं।

http://svn.process-one.net/contribs/trunk/eunit/doc/overview-summary.html

1

मैं कैसे अपने आप को अभिनेता का परीक्षण करने के बारे में सोच की है।

यहां मैं क्या आया हूं, क्या कोई इस दृष्टिकोण के साथ समस्याएं देखता है?

सीधे संदेश भेजने की बजाय, क्या होगा यदि आपके अभिनेता ने एक समारोह में संदेश भेज दिया हो?

:

class MyActor extends Actor { 

    var sendMessage:(Actor, ContactMsg) => Unit = { 
    (contactActor, msg) => { 
     Log.trace("real sendMessage called") 
     contactActor ! msg 
    } 
    } 

    var reactImpl:PartialFunction(Any, Unit) = { 
     case INCOMING(otherActor1, otherActor2, args) => { 

     /* logic to test */ 
     if(args){ 
      sendMessage(otherActor1, OUTGOING_1("foo")) 

     } else { 
      sendMessage(otherActor2, OUTGOING_2("bar")) 
     } 
     } 
    } 

    final def act = loop { 
    react { 
     reactImpl 
    } 
    } 

आपका परीक्षण का मामला की तरह कोड शामिल हो सकता है:

फिर अपने परीक्षण है कि एक बार कहा जाता है और/या तर्क की संख्या है जिसके साथ विधि बुलाया गया था पटरियों के साथ समारोह बाहर स्वैप कर सकते हैं

// setup the test 
var myActor = new MyActor 
var target1 = new MyActor 
var target2 = new MyActor 
var sendMessageCalls:List[(Actor, String)] = Nil 

/* 
* Create a fake implementation of sendMessage 
* that tracks the arguments it was called with 
* in the sendMessageCalls list: 
*/ 
myActor.sendMessage = (actor, message) => { 
    Log.trace("fake sendMessage called") 
    message match { 
    case OUTGOING_1(payload) => { 
     sendMessageCalls = (actor, payload) :: sendMessageCalls 
    } 
    case _ => { fail("Unexpected Message sent:"+message) } 
    } 
} 

// run the test 
myActor.start 
myActor.reactImpl(Incoming(target1, target2, true)) 

// assert the results 
assertEquals(1, sendMessageCalls.size) 
val(sentActor, sentPayload) = sendMessageCalls(0) 
assertSame(target1, sentActor) 
assertEquals("foo", sentPayload) 
// .. etc. 
+0

मुझे लगता है कि डेनियल इस तरह बनाया गया एक नकली अभिनेता के साथ ऊपर की परीक्षा में target1 और target2 की जगह की बात कर रहा है: वर target1 = अभिनेता {{प्रतिक्रिया मामले OUTGOING_1 (पेलोड) {/ * एक ध्वज सेट या पेलोड संलग्न .. । * /}}} लेकिन मेरे संदेशों में अक्सर केवल अभिनेता आईडी होती है। एक निर्देशिका अभिनेता है जो आईडी द्वारा की गई अभिनेता को संदेश भेजता है। तो SendMessage के कार्यान्वयन को स्वैप करने के बजाय, मैं relayMessage को स्वैप कर दूंगा। कोड को ऊपर से ऊपर रखने के लिए, मैंने यह सब छोड़ दिया। लेकिन सामान्य विचार वही है। –

1

एक अभिनेता (यह काम करता है) इकाई परीक्षण में मेरा प्रयास। मैं एक फ्रेमवर्क के रूप में Specs का उपयोग कर रहा हूँ।

object ControllerSpec extends Specification { 
    "ChatController" should{ 
    "add a listener and respond SendFriends" in{ 
     var res = false 
     val a = actor{} 
     val mos = {ChatController !? AddListener(a)} 
     mos match{ 
      case SendFriends => res = true 
      case _ => res = false 
     } 
     res must beTrue 
    } 

यह कैसे काम करता है सिंगलटन ChatController को एक तुल्यकालिक कॉल भेजकर। ChatController उत्तर() के उपयोग से प्रतिक्रिया देता है। प्रतिक्रिया को बुलाए गए फ़ंक्शन की वापसी के रूप में भेजा जाता है, जो मोस में संग्रहीत हो जाता है। फिर चैटकंट्रोलर से भेजे गए केस क्लास को प्राप्त करने के लिए एक मैच लागू किया जाता है। यदि परिणाम अपेक्षित है (SendFriends) सेट को सही पर सेट करें। res होना चाहिए ट्राउ दावा परीक्षण की सफलता या विफलता निर्धारित करता है।

मेरे अभिनेता सिंगलटन कि मैं

import ldc.socialirc.model._ 

import scala.collection.mutable.{HashMap, HashSet} 
import scala.actors.Actor 
import scala.actors.Actor._ 

import net.liftweb.util.Helpers._ 

//Message types 
case class AddListener(listener: Actor) 
case class RemoveListener(listener: Actor) 
case class SendFriends 
//Data Types 
case class Authority(usr: Actor, role: String) 
case class Channel(channelName: String, password: String, creator: String, motd: String, users: HashSet[Authority]) 

object ChatController extends Actor { 
    // The Channel List - Shows what actors are in each Chan 
    val chanList = new HashMap[String, Channel] 
    // The Actor List - Shows what channels its in 
    val actorList = new HashMap[Actor, HashSet[String]] 

    def notifyListeners = { 

    } 

    def act = { 
     loop { 
      react { 
       case AddListener(listener: Actor)=> 
        actorList += listener -> new HashSet[String] 
        reply(SendFriends) 

      } 
     } 
    } 
    start //Dont forget to start 
} 

हालांकि इसके पूरा नहीं यह Sendfriends मामले वर्ग वापसी करता है के रूप में उम्मीद का परीक्षण कर रहा हूँ।

0

अभिनेताओं के यूनिट परीक्षण के लिए सूट हाल ही में Akka में जोड़ा गया है। आप this ब्लॉगपोस्ट में कुछ जानकारी और कोड स्निपेट पा सकते हैं।