2015-03-26 7 views
8

मैं एक्का टेस्टकिट के साथ स्कालाटेस्ट का उपयोग यूनिट लिखने और एक अभिनेता के लिए एकीकरण परीक्षण के लिए कर रहा हूं जिसे मैंने किसी अन्य अभिनेता को किसी भी आंतरिक राज्य को बिना किसी संदेश के भेजने के लिए कोड भेजा है। उदाहरण के लिए यह लो:मैं एक अक्का अभिनेता का परीक्षण कैसे करूं जो किसी अन्य अभिनेता को संदेश भेजता है?

class MyActor extends Actor { 
    val anotherActor = context.actorOf(Props[AnotherActor]) 
    def receive: Receive = { 
    case MyMessage => anotherActor ! AnotherMessage 
    } 
} 

मैं एक परीक्षण है कि पुष्टि की है कि anotherActorMyActor प्रसंस्करण MyMessage का एक परिणाम के रूप में संसाधित AnotherMessage लिखना चाहते हैं।

val testActorRef = TestActorRef(new MyActor) 
"MyActor" should "change some internal state when it receives MyMessage" in { 
    testActorRef ! MyMessage 
    testActorRef.underlyingActor.someState shouldBe "altered" 
} 

लेकिन मेरे मामले में मैं इस तरह के स्थिति के बारे में परवाह नहीं है में: क्लासिक उदाहरण TestActorRef उपयोग करने के लिए अंतर्निहित अभिनेता पर मिलता है और कुछ आंतरिक स्थिति है कि इतनी तरह संदेश प्राप्त होने पर प्रभावित किया जाना चाहिए था की जांच करने के लिए है। वास्तव में, मैं इस तरह के किसी भी राज्य को पकड़ने से बचना चाहता हूं। TestProbe काफी कुछ नहीं था जिसे मैं ढूंढ रहा था क्योंकि आपको अभी भी अभिनेता के साथ TestProbe.ref पंजीकरण करना है। अधिकांश भाग के लिए, मैंने परीक्षण पर अक्का दस्तावेज के सभी उदाहरणों को देखा है (http://doc.akka.io/docs/akka/snapshot/scala/testing.html) लेकिन कुछ भी उपयुक्त नहीं मिला है।

उत्तर

14

ऐसा करने के कुछ तरीके हैं, मैं आपको दिखाऊंगा जो काम करता है जब हमारे पास परीक्षण के समान कुछ होता है। मुझे अभी भी लगता है कि TestActorRef, TestKit और TestProbe जाने का रास्ता हैं। निम्नलिखित संरचना को ध्यान में रखते:

case object MyMessage 
case object AnotherMessage 

class MyActor extends Actor { 
    val anotherActor = createAnother 
    def receive: Receive = { 
    case MyMessage => anotherActor ! AnotherMessage 
    } 

    def createAnother = context.actorOf(Props[AnotherActor]) 
} 

class AnotherActor extends Actor{ 
    def receive = { 
    case _ => 
    } 
} 

मुद्दा आप एक बाल कलाकार और अपने परीक्षण के हिस्से के रूप में आप यह सुनिश्चित करें कि बच्चे को अपने परीक्षण में भी आप हालांकि संदेश हो जाता है नहीं है बनाने की जरूरत है बनाने एक अभिनेता के उदाहरण है कि है उस बच्चे के निर्माण में कोई नियंत्रण है। जब हम इस स्थिति है, हम कुछ निम्नलिखित की तरह सरल कर (specs2 का उपयोग किया जाता है, लेकिन ScalaTest में कुछ इसी तरह बनाने के लिए सक्षम होना चाहिए):

import akka.actor._ 
import akka.testkit._ 
import org.specs2.mutable.SpecificationLike 
import org.specs2.runner.JUnitRunner 
import org.junit.runner.RunWith 

class MessageSendingSpec extends TestKit(ActorSystem("test")) with SpecificationLike{ 

    val probe = TestProbe() 
    val myActor = TestActorRef(new MyActor{ 
    override def createAnother = probe.ref 
    }) 


    "Sending MyMessage to an instance of MyActor" should{ 
    "pass AnotherMessage to the child AnotherActor" in { 
     myActor ! MyMessage 
     probe.expectMsg(AnotherMessage) 
     success 
    } 
    } 
} 

कुंजी है कि जब अभिनेता बनाने का परीक्षण करने, मैं मेरी जांच की आपूर्ति करने के लिए बच्चे को बनाता है जो विधि को ओवरराइड करें। यह कच्चा है, लेकिन यह भी सरल और प्रभावी है।

+0

बिल्कुल वही जो मैं खोज रहा था! मैंने बाल कलाकारों को एक विधि के साथ बनाने का भी विचार नहीं किया था जिसे मैं 'TestProbe.ref' में छोड़ने के लिए ओवरराइड कर सकता था। धन्यवाद @cmbaxter, – nmurthy

+0

अगर हम विधि प्राप्त करने के अंदर बनाए गए एक और अभिनेता हैं तो हम यह कैसे करते हैं? –

+0

जावा में इसे कैसे कार्यान्वित किया जा सकता है? –

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