Created
September 24, 2015 18:29
-
-
Save sam/d939b8a4988c419f9742 to your computer and use it in GitHub Desktop.
Hard to get current class-name for your TestKit ActorSystem. This hack gets around constructor issues.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // The TestKit class is just: | |
| class TestKit(_system: ActorSystem) extends { implicit val system = _system } with TestKitBase | |
| // TestKitBase uses `system` in it's constructor so _it must be defined before extending TestKitBase_! | |
| // You can't use `this` within alternate constructors however, so the solution isn't as easy as: | |
| class MySpec extends TestKit(ActorSystem(this.getClass.getSimpleName)) | |
| // So let's ignore `TestKit` and focus on `TestKitBase`. That way we can have our own constructors that execute before | |
| // TestKitBase's constructor. | |
| class Foo extends { val name = this.getClass.getSimpleName } | |
| // unfortunately you can't use `this` within an anonymous superclass definition like that. So we can't use the | |
| // same strategy that `TestKit` does. We'll have to use a concrete class instead: | |
| // It's very important we extend our trait before `TestKitBase`, but | |
| // since our only subclass is in the same file we don't need to worry | |
| // too much about that. | |
| protected[this] trait TestKitActorSystemSupport { | |
| // Finally we have a place we can legally call `this`. Our trait's default constructor: | |
| private val normalizedClassName: String = this.getClass | |
| .getName | |
| .replace("com.wieck.migration.", "") | |
| .replaceAll("[^a-zA-Z0-9]", "-") | |
| // And now we can satisfy `TestKitBase` so when it's constructor attempts to | |
| // access `system` it won't be abstract and throw an NPE. | |
| implicit val system: ActorSystem = ActorSystem(s"$normalizedClassName-testkit") | |
| } | |
| // Again, very important we extend `TestKitActorSystemSupport` first, but otherwise | |
| // anything else we decide to put here is gravy. We don't even have to worry about | |
| // making `AkkaSpec` itself an `abstract class` since we're guaranteeing a working | |
| // constructor order here. | |
| trait AkkaSpec extends TestKitActorSystemSupport with TestKitBase with ImplicitSender with DefaultTimeout with Spec { | |
| implicit val ec: ExecutionContext = system.dispatcher | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment