Akka TestKit如何等待处理消息

时间:2015-07-08 16:20:03

标签: scala akka akka-testkit

在我的TestKit测试中

"A History Actor" must {

    // given
    val historyActorRef = TestActorRef(new HistoryActor("history-file.log"))       // Creation of the TestActorRef
    val writerActorRef = TestActorRef(new WriterActor("history-file.log"))       // Creation of the TestActorRef

    historyActorRef.underlyingActor.writerActor = writerActorRef

    "receive messages and change state" in {  // integration-like test

      // This call is synchronous. The actor receive() method will be called in the current thread

      // when
      historyActorRef ! WriteMsg("line 1")

      // then (1) - got WriteResult (from WriterActor as result of getting WriteMsg)
      within(200 millis) {
        expectMsg(WriteResult(1, 7))
      }

      // then (2) - state
      historyActorRef.underlyingActor.lastWrite must equal(WriteResult(1,7)) // With actorRef.underlyingActor, we can access the react actor instance created by Akka
    }
  }

此测试失败,因为它仍然是WriteResult(0,0)

HistoryActor的工作方式:

   case cmd: WriteMsg => {

      log.info("forwarding " + cmd + " to the writer" )

      writerActor ! cmd

    }

    case result: WriteResult => {

      log.info("WriteResult: " + result)

      lastWrite = result                  // update the state

    } 

那么,当我们检查结果时,如何进行测试以确保WriteResult已经处理过?

P.S。  我想我应该考虑单独测试WriterActor,但让我们说我想进行类似集成的测试。

1 个答案:

答案 0 :(得分:1)

如果你还没有这样做,你需要在TestActorRef s中包装这两个被测试的演员。这将确保两者都使用调用线程调度程序从测试场景中获取异步性。您也可以考虑将writeActor替换为TestProbe进行测试,然后模拟其行为。

<强>更新

根据我的意见:

当您说expectMsg时,您所说的是测试本身(由TestKit引入的隐式发件人)正在从最初发送的消息中接收响应消息以启动测试。我不认为这是你想要断言的,因此我建议你删除它。我认为你试图说写作者收到了那条消息,但这不是测试工具包断言的工作方式。只需验证内部状态是否已更新就足够了