2014-11-23 70 views
2

我有以下特點阿卡 - 測試,從測試功能執行

trait MyTrait{ 

    def printHelloWorld(){ 
    println("hello world") 
    } 

} 

case object SayHello 

class MyActor extends Actor with MyTrait{ 

    def recieve = { 
     case SayHello => printHelloWorld 
    } 
} 

現在,我想創建單元測試,其測試,然後打個招呼對象調用打印hello消息

"My Actor" should{ 
    "println hello msg if SayHello sent" in{ 
     val myTraitMock = mock[MyTrait] 

     val myActor = system.actorOf(Props(new MyActor)) 
     myActor ! SayHello 

     Thread.sleep(500) 
     there was atLeastOne(myTraitMock).printHelloMessage 
    } 
} 

然而這個單元測試總是綠色的。即使我用簡單的println方法替換這個方法。

有沒有其他的方法來測試這種情況?

回答

2

如何:

trait MyActor extends Actor{self:MyTrait 

    def recieve = { 
     case SayHello => printHelloWorld 
    } 
} 

class MyMainActor extends MyActor with MyTrait 

"My Actor" should{ 
"println hello msg if SayHello sent" in{ 
    class MockActor extends MyActor with SomeMyTrait 

     val x = new MockActor 
     val myActor = system.actorOf(Props(x)) 
     myActor ! SayHello 

     Thread.sleep(500) 
     there was atLeastOne(x).printHelloMessage 
    } 

一般的演員,我不像測試上方的風扇。 阿卡Test-kit是輝煌的。我強烈建議看看它。

在其中,我會做:

trait MyTrait{ 

    def printHelloWorld(){ 
    println("hello world") 

    } 

} 

case object SayHello 
case object Printed 

class MyActor extends Actor with MyTrait{ 

    def recieve = { 
     case SayHello => printHelloWorld 
         sender ! Printed 
    } 
} 

import akka.actor.ActorSystem 
import akka.testkit.{ TestProbe, ImplicitSender, TestKit } 
import org.scalatest.matchers.ShouldMatchers 
import org.scalatest.{ BeforeAndAfterAll, FunSuite }  
import scala.concurrent.duration._ 

class MyTest extends TestKit(ActorSystem("MyTest1")) 
    with FunSuite 
    with BeforeAndAfterAll 
    with ShouldMatchers 
    with ImplicitSender{ 

    override def afterAll() { system.shutdown() } 
    test("MyTrait is called when triggered") { 
    val x = TestProbe() 
    val myActor = system.actorOf(Props(new MyActor)) 
    myActor.send(x, SayHello) 
    x.expectMsg(Printed) 

} 
+0

你需要'libraryDependencies + =「 org.scalatest「%%」scalatest「%」1.9.1「%」test「'和'libraryDependencies + =」com.typesafe.akka「%%」akka-testkit「%」2.2.3「'作爲依賴項 – Jatin 2014-11-23 17:15:41

+0

這就是不錯,我非常喜歡Akka-test,但MyActor不應該向發件人返回任何消息。它只是「火和遺忘」,我可以在測試過程中用其他特性擴展它,以便將消息返回給發件人。這是我看到的唯一選項。 – 2014-11-23 17:19:11

0

您可以測試對什麼是打印到EventFilter。所以,如果你的演員將打印信息這樣的:

case _ => log.info(printMessage) 

然後你可以測試

EventFilter.info(start="hello world", occurences=1).intercept { 
    MyActor ! SayHello 
} 
1

我知道這是一個老問題,但我有同樣的用例(發射後不管)和我想出了用探針一個簡單的解決方案:

case object SayHello 

class MyActor(f:() => Unit) extends Actor{ // pass function as a parameter 
    def receive = { 
    case SayHello => f() 
    } 
} 

現在如果你想創建一個測試:

"test" { 
    val probe = TestProbe() 

    case object Executed 

    def mockF():Unit = { 
     println("test") 
     probe.ref ! Executed 
    } 

    val testActor = TestActorRef(Props(new MyActor(mockF))) 
    testActor ! SayHello 
    //probe.expectMsg blocks the thread, so it'll wait for Executed message. 
    probe.expectMsgPF(){case Executed => 1} 

    } 

如果你不希望傳遞一個函數作爲參數,那麼你可以做同樣的事情與性狀:

trait MyTraitImpl extends MyTrait{ 
    def printHelloWorld(){ 
    println("hello world") 
     } 
} 

trait MyTrait{ 
    def printHelloWorld() 
} 

case object SayHello 

class MyActor extends Actor{ 
    myTrait:MyTrait => 

    def receive = { 
    case SayHello => printHelloWorld 
    } 
} 

和測試:

"test" { 
    val probe = TestProbe() 

    case object Executed 

    trait MyTraitMock extends MyTrait{ 
     def printHelloWorld(){ 
     println("hello world") 

     probe.ref ! Executed 
     } 
    } 

    val testActor = TestActorRef(Props(new MyActor() with MyTraitMock)) 
    testActor ! SayHello 

    probe.expectMsgPF(){case Executed => 1} 

    } 
+0

我不確定這是否適用於所有情況,但在我的情況下,我需要驗證某個注入對象的某個方法是否被調用,所以它很好。測試探測器不是必需的,至少不適用於Akka.NET,您可以訪問由TestKit創建的底層測試actor:this.TestActor.Tell(「foo」);和this.ExpectMsg( 「foo」 的);'。 – Stijn 2017-10-26 15:06:25