Akka Persistence Testkitを動かすまでの手順をメモっておく
Akka Version 2.6.5ぐらいから、Akka Persistence Testkitなるライブラリが出ていたそうで、ちょっと動かしてみたので、そのときにやってことをメモ。
そのときのコードは、以下です。
以下、手順とかコードとか書きます。
build.sbt
まずは、build.sbtの作り方から。
とはいえ、依存ライブラリを必要なものを最低限入れるだけ。
val akkaVersion = "2.6.6" lazy val root = (project in file(".")) .settings( name := "akka-sample-persistence", version := "0.1", scalaVersion := "2.13.3", libraryDependencies ++= Seq( "com.typesafe.akka" %% "akka-actor-typed" % akkaVersion, "com.typesafe.akka" %% "akka-persistence-typed" % akkaVersion, "com.typesafe.akka" %% "akka-slf4j" % akkaVersion, "com.typesafe.akka" %% "akka-serialization-jackson" % akkaVersion, "ch.qos.logback" % "logback-classic" % "1.2.3", "com.typesafe.akka" %% "akka-actor-testkit-typed" % akkaVersion % Test, "com.typesafe.akka" %% "akka-persistence-testkit" % akkaVersion % Test, "org.scalatest" %% "scalatest" % "3.2.0" % Test ) )
必要なライブラリのポイントとしては、 Serialization
と logback
あたりかなーと。
Serialization
AkkaのDocumentに書いてあるサンプルのコードを動かそうと思うと、
ここに書いてあるサンプルのActorでテストをしようとしている。
その中で、 CborSerializable
がActorのプロトコルにextendsされている。
これは、Akka Persistenceで永続化するときに、どうやってSerializeしますかーってあたりの解決をしてあげる必要がある。
このあたりのSerializationの解決は、以下のドキュメントに書いてあるあたりを参考にする。
というのも、今回のドキュメントで、 EventSourcedBehaviorTestKit
なるTestKitを試そうとしているのだが、その初期設定値でSerializationはちゃんと指定しろよ的なことになっているようなので。
logback
サンプルのテストコードの中で LogCapturing
を指定しているので、logback-test.xmlを作ってって対応をする必要がある。
このドキュメントで紹介されている LogCapturing
を使いたいみたいなので、logbackの依存がいるし、ここに記載されている logback-test.xml
を test/resources
ディレクトリの配下に作ってあげないとだめ。
サンプルのActor
Akkaのドキュメントに書いてあるAccountの前にもちょっと簡単なActorを作った。
これもドキュメントに書いてるコードだけど、一部、自分でちょちょっとイジってるけど。
object MyPersistentBehavior { sealed trait Command extends CborSerializable final case class Add(data: String) extends Command case object Clear extends Command sealed trait Event extends CborSerializable final case class Added(data: String) extends Event case object Cleared extends Event final case class State(history: List[String]) extends CborSerializable private val commandHandler: (State, Command) => Effect[Event, State] = (state, command) => command match { case Add(data) => Effect.persist(Added(data)) case Clear => Effect.persist(Cleared) } private val eventHandler: (State, Event) => State = (state, event) => event match { case Added(data) => state.copy((data :: state.history).take(5)) case Cleared => State(Nil) } def apply(id: String): Behavior[Command] = EventSourcedBehavior[Command, Event, State]( persistenceId = PersistenceId.ofUniqueId(id), emptyState = State(Nil), commandHandler, eventHandler ) }
コード自体は、Akka Persistenceの EventSourcedBehavior
をapplyする典型的な例になっている。
ポイントは、 CborSerializable
なるtraitを自分で作っている。
trait CborSerializable {}
こんな感じで。
これを、TestクラスのConfigあたりで、良い感じにSerializeするクラスはこれですよー的な感じで指定してやると、簡単にSerializeされるようになる。
サンプルのTest
class MyPersistentBehaviorSpec extends ScalaTestWithActorTestKit( ConfigFactory .parseString(""" |akka { | actor { | serializers { | jackson-cbor = "akka.serialization.jackson.JacksonCborSerializer" | } | serialization-bindings { | "com.github.yoshiyoshifujii.akka.sample.persistence.serialization.CborSerializable" = jackson-cbor | } | } |} |""".stripMargin).withFallback(EventSourcedBehaviorTestKit.config) ) with AnyWordSpecLike with BeforeAndAfterEach with LogCapturing { private val eventSourcedTestKit = EventSourcedBehaviorTestKit[MyPersistentBehavior.Command, MyPersistentBehavior.Event, MyPersistentBehavior.State]( system, MyPersistentBehavior("id-1") ) override protected def beforeEach(): Unit = { super.beforeEach() eventSourcedTestKit.clear() } "MyPersistentBehavior" must { "Add" in { val result = eventSourcedTestKit.runCommand(MyPersistentBehavior.Add("data-1")) result.stateOfType[MyPersistentBehavior.State].history should contain("data-1") } } }
こんな感じ。
Akkaのドキュメント見てると、 extends ScalaTestWithActorTestKit(EventSourcedBehaviorTestKit.config)
みたいな感じでしれっといけそうに書いてあるのだが、デフォでSerializationを指定しないといけなくなっているので、ConfigFactoryでそのあたりを指定してやる必要がある。
ここで、作っておいた CborSerializable
を良い感じに指定してあげているので、ちゃんとテストが動くはず。
まとめ
これで、Akka Persistenceのテストいろいろと試せるぜー
なお、ドキュメントでは、このTestKitは新しくできたばっかりで将来変わる可能性あるよってあるので、この記事は期間限定で使える感じになりそう。
ので、詳しくは、Akkaのドキュメント読んでね。
以上です。