简体   繁体   中英

scalaTest:method run in trait WordSpecLike of type org.scalatest.Status needs `abstract override' modifiers

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:

  • WordSpecLike has a concrete implementation of run
  • BeforeAndAfterAll can only be mixed in if the base class or one of the previous traits already implements 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM