2014-11-23 34 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