Skip to content

Instantly share code, notes, and snippets.

@sam
Created September 24, 2015 18:29
Show Gist options
  • Select an option

  • Save sam/d939b8a4988c419f9742 to your computer and use it in GitHub Desktop.

Select an option

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.
// 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