我有以下特质
trait MyTrait{
def printHelloWorld(){
println("hello world")
}
}
case object SayHello
class MyActor extends Actor with MyTrait{
def recieve = {
case SayHello => printHelloWorld
}
}
现在我正在尝试创建单元测试,然后测试然后Say Hello Object调用打印问候消息
"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方法替换这个方法。
有没有其他方法来测试这种情况?
答案 0 :(得分: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)
}
答案 1 :(得分:1)
我知道这是一个老问题,但我有相同的用例(火灾和遗忘),我想出了一个使用Probe的简单解决方案:
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}
}
答案 2 :(得分:0)
您可以测试打印到EventFilter
的内容。所以如果你的演员会打印这样的信息:
case _ => log.info(printMessage)
然后你可以测试
EventFilter.info(start="hello world", occurences=1).intercept {
MyActor ! SayHello
}