Merge pull request #18214 from ktoso/wip-18061-testactorref-dislikes-persistentactor-ktoso

=per,doc #18061 doc that Persistence won't work with TestActorRef
This commit is contained in:
Konrad Malawski 2015-08-14 13:49:23 +02:00
commit 9422baf5a2
6 changed files with 37 additions and 7 deletions

View file

@ -853,6 +853,14 @@ or
in your Akka configuration. The LevelDB Java port is for testing purposes only. in your Akka configuration. The LevelDB Java port is for testing purposes only.
.. warning::
It is not possible to test persistence provided classes (i.e. :ref:`PersistentActor <event-sourcing-java>`
and :ref:`AtLeastOnceDelivery <at-least-once-delivery-java>`) using ``TestActorRef`` due to its *synchronous* nature.
These traits need to be able to perform asynchronous tasks in the background in order to handle internal persistence
related events.
When testing Persistence based projects always rely on :ref:`asynchronous messaging using the TestKit <async-integration-testing-java>`.
Multiple persistence plugin configurations Multiple persistence plugin configurations
========================================== ==========================================

View file

@ -844,6 +844,14 @@ or
in your Akka configuration. The LevelDB Java port is for testing purposes only. in your Akka configuration. The LevelDB Java port is for testing purposes only.
.. warning::
It is not possible to test persistence provided classes (i.e. :ref:`PersistentActor <event-sourcing-java>`
and :ref:`AtLeastOnceDelivery <at-least-once-delivery-java>`) using ``TestActorRef`` due to its *synchronous* nature.
These traits need to be able to perform asynchronous tasks in the background in order to handle internal persistence
related events.
When testing Persistence based projects always rely on :ref:`asynchronous messaging using the TestKit <async-integration-testing-java>`.
Configuration Configuration
============= =============

View file

@ -70,6 +70,7 @@ section below.
to ask the Actor to reply with the state you want to run assertions against), to ask the Actor to reply with the state you want to run assertions against),
instead of using ``TestActorRef`` whenever possible. instead of using ``TestActorRef`` whenever possible.
.. warning::
Due to the synchronous nature of ``TestActorRef`` it will **not** work with some support Due to the synchronous nature of ``TestActorRef`` it will **not** work with some support
traits that Akka provides as they require asynchronous behaviours to function properly. traits that Akka provides as they require asynchronous behaviours to function properly.
Examples of traits that do not mix well with test actor refs are :ref:`PersistentActor <event-sourcing-java>` Examples of traits that do not mix well with test actor refs are :ref:`PersistentActor <event-sourcing-java>`
@ -151,6 +152,8 @@ Feel free to experiment with the possibilities, and if you find useful
patterns, don't hesitate to let the Akka forums know about them! Who knows, patterns, don't hesitate to let the Akka forums know about them! Who knows,
common operations might even be worked into nice DSLs. common operations might even be worked into nice DSLs.
.. _async-integration-testing-java:
Asynchronous Integration Testing with :class:`JavaTestKit` Asynchronous Integration Testing with :class:`JavaTestKit`
========================================================== ==========================================================

View file

@ -897,6 +897,14 @@ or
in your Akka configuration. The LevelDB Java port is for testing purposes only. in your Akka configuration. The LevelDB Java port is for testing purposes only.
.. warning::
It is not possible to test persistence provided classes (i.e. :ref:`PersistentActor <event-sourcing-scala>`
and :ref:`AtLeastOnceDelivery <at-least-once-delivery-scala>`) using ``TestActorRef`` due to its *synchronous* nature.
These traits need to be able to perform asynchronous tasks in the background in order to handle internal persistence
related events.
When testing Persistence based projects always rely on :ref:`asynchronous messaging using the TestKit <async-integration-testing-scala>`.
Configuration Configuration
============= =============

View file

@ -59,6 +59,7 @@ section below.
to ask the Actor to reply with the state you want to run assertions against), to ask the Actor to reply with the state you want to run assertions against),
instead of using ``TestActorRef`` whenever possible. instead of using ``TestActorRef`` whenever possible.
.. warning::
Due to the synchronous nature of ``TestActorRef`` it will **not** work with some support Due to the synchronous nature of ``TestActorRef`` it will **not** work with some support
traits that Akka provides as they require asynchronous behaviours to function properly. traits that Akka provides as they require asynchronous behaviours to function properly.
Examples of traits that do not mix well with test actor refs are :ref:`PersistentActor <event-sourcing>` Examples of traits that do not mix well with test actor refs are :ref:`PersistentActor <event-sourcing>`
@ -160,6 +161,8 @@ Feel free to experiment with the possibilities, and if you find useful
patterns, don't hesitate to let the Akka forums know about them! Who knows, patterns, don't hesitate to let the Akka forums know about them! Who knows,
common operations might even be worked into nice DSLs. common operations might even be worked into nice DSLs.
.. _async-integration-testing-scala:
Asynchronous Integration Testing with :class:`TestKit` Asynchronous Integration Testing with :class:`TestKit`
====================================================== ======================================================

View file

@ -5,7 +5,7 @@
package akka.persistence.fsm package akka.persistence.fsm
import akka.actor._ import akka.actor._
import akka.persistence.{PersistentActor, RecoveryCompleted, PersistenceSpec} import akka.persistence.{ PersistentActor, RecoveryCompleted, PersistenceSpec }
import akka.persistence.fsm.PersistentFSM._ import akka.persistence.fsm.PersistentFSM._
import akka.testkit._ import akka.testkit._
import com.typesafe.config.Config import com.typesafe.config.Config
@ -266,13 +266,13 @@ abstract class PersistentFSMSpec(config: Config) extends PersistenceSpec(config)
val persistentEventsStreamer = system.actorOf(PersistentEventsStreamer.props(persistenceId, testActor)) val persistentEventsStreamer = system.actorOf(PersistentEventsStreamer.props(persistenceId, testActor))
expectMsg(ItemAdded(Item("1", "Shirt", 59.99F))) expectMsg(ItemAdded(Item("1", "Shirt", 59.99F)))
expectMsgType[StateChangeEvent] //because a timeout is defined, State Change is persisted expectMsgType[StateChangeEvent] //because a timeout is defined, State Change is persisted
expectMsg(ItemAdded(Item("2", "Shoes", 89.99F))) expectMsg(ItemAdded(Item("2", "Shoes", 89.99F)))
expectMsgType[StateChangeEvent] //because a timeout is defined, State Change is persisted expectMsgType[StateChangeEvent] //because a timeout is defined, State Change is persisted
expectMsg(ItemAdded(Item("3", "Coat", 119.99F))) expectMsg(ItemAdded(Item("3", "Coat", 119.99F)))
expectMsgType[StateChangeEvent] //because a timeout is defined, State Change is persisted expectMsgType[StateChangeEvent] //because a timeout is defined, State Change is persisted
expectMsg(OrderExecuted) expectMsg(OrderExecuted)
expectMsgType[StateChangeEvent] expectMsgType[StateChangeEvent]
@ -431,13 +431,13 @@ object PersistentFSMSpec {
def props(persistenceId: String, reportActor: ActorRef) = def props(persistenceId: String, reportActor: ActorRef) =
Props(new WebStoreCustomerFSM(persistenceId, reportActor)) Props(new WebStoreCustomerFSM(persistenceId, reportActor))
} }
class PersistentEventsStreamer(id: String, client: ActorRef) extends PersistentActor { class PersistentEventsStreamer(id: String, client: ActorRef) extends PersistentActor {
override val persistenceId: String = id override val persistenceId: String = id
def receiveRecover = { def receiveRecover = {
case RecoveryCompleted // do nothing case RecoveryCompleted // do nothing
case persistentEvent client ! persistentEvent case persistentEvent client ! persistentEvent
} }
def receiveCommand = { def receiveCommand = {