I'm trying to write unit test for Akka Actor.
Below is the Unit Test Code
import org.scalatest._
import akka.testkit.{TestKit, ImplicitSender, TestActors}
import akka.actor.ActorSystem
class PipFilterTest
extends TestKit(ActorSystem("testSystem"))
with BeforeAndAfterAll
with ImplicitSender
with WordSpecLike {
override def afterAll(): Unit = {
TestKit.shutdownActorSystem(system)
}
"PipeFilter Actor" must {
"send messages if it passes the filter criteria" in {
//test code
}
}
}
When I try to run the test code I get below error -
sbt:chapter8_structuralPatterns> test
[info] Compiling 1 Scala source to /rajkumar_natarajans_directory/projectName/target/scala-2.12/test-classes ...
[error] /rajkumar_natarajans_directory/projectName/src/test/scala/PipeFilterTest.scala:13:7: overriding method run in trait BeforeAndAfterAll of type (testName: Option[String], args: org.scalatest.Args)org.scalatest.Status;
[error] method run in trait WordSpecLike of type (testName: Option[String], args: org.scalatest.Args)org.scalatest.Status needs `abstract override' modifiers
[error] class PipFilterTest extends TestKit(ActorSystem("testSystem")) with StopSystemAfterAll with ImplicitSender with WordSpecLike {
[error] ^
[error] one error found
[error] (Test / compileIncremental) Compilation failed
When I remove with BeforeAndAfterAll
and beforeAll
and afterAll
methods then test runs fine. But I need these for setup test actors.
Any idea why I get these error.
Version information:
scalaTest 3.0.5
akka 2.5.11
scala 2.12.4
This here compiles and runs with scalac 2.12.4, akka 2.5.11, scalaTest 3.0.5:
import org.scalatest._
import akka.testkit.{TestKit, ImplicitSender, TestActors}
import akka.actor.ActorSystem
class PipFilterTest
extends TestKit(ActorSystem("testSystem"))
with WordSpecLike
with ImplicitSender
with BeforeAndAfterAll {
override def afterAll(): Unit = {
TestKit.shutdownActorSystem(system)
}
"PipeFilter Actor" must {
"send messages if it passes the filter criteria" in {
//test code
}
}
}
The reason was:
run
run
If you swap WordSpecLike
and BeforeAndAfterAll
, then the compiler thinks that you want to mixin WordSpecLike
, but BeforeAndAfterAll
then has nothing to rely on, because there is no trait before it that implements run
, and therefore the whole compilation fails.
That's actually quite intuitive: the run
of BeforeAndAfterAll
should looks somewhat like this:
abstract override def run(): CrazyScalatestResultType = {
beforeAll()
super.run()
afterAll()
}
If there is no super
that implements run
, then BeforeAndAfterAll
also cannot function correctly.
Takeaway: order of mixins is significant.
Possibly relevant link: Scala's Stackable Trait Pattern