Reeebuuk Reeebuuk - 4 months ago 35
Scala Question

Mocking child actor in Akka

I'm trying to write unit tests for my actor and am stuck on basic mocking.
PriceAggregateActor is using akka persistence and I don't want to pass in all the conf for it and would like to mock it completely.

This is the actor that I want to test

object CommandPriceActor {
def apply() = Props(classOf[CommandPriceActor], PriceAggregateActor())
}

class CommandPriceActor(priceAggregateActorProps: Props) extends Actor with ActorLogging {

val priceAggregateActor = context.actorOf(priceAggregateActorProps, "priceAggregateActor")


So in my tests I'm trying to do something like:

class CommandPriceActorTest extends TestKit(ActorSystem("test-benefits",
ConfigFactory.parseString("""akka.loggers = ["akka.testkit.TestEventListener"] """))) with FlatSpecLike with Matchers
with BeforeAndAfterAll with Eventually{

class MockedChild extends Actor {
def receive = {
case _ => lala
}
}

val probe = TestProbe()
val commandPriceActor = TestActorRef(new CommandPriceActor(Props[MockedChild]))


I'm always getting:

Caused by: java.lang.IllegalArgumentException: no matching constructor found on class CommandPriceActorTest$MockedChild for arguments []


Why is it complaining about mockedChild? It shouldn't take any constructor arguments.

Answer

This is because MockedChild is a child actor of your test. The missing constructor argument is the reference to the test (which is the parent class).

You have three options: * Pass the reference to this into Props * Use the named parameter form of Props * Make MockedChild a top level class (or member of an object)

Option 1

val probe = TestProbe()
val mockProps = Props(classOf[MockedChild], this)
val commandPriceActor = TestActorRef(new CommandPriceActor(mockProps))

Option 2

val probe = TestProbe()
val mockProps = Props(new MockedChild)
val commandPriceActor = TestActorRef(new CommandPriceActor(mockProps))

Option 3

val probe = TestProbe()
val mockProps = Props(new CommandPriceActorTest.MockedChild)
val commandPriceActor = TestActorRef(new CommandPriceActor(mockProps))

// ....

object CommandPriceActorTest {
  class MockedChild extends Actor {
    def receive = {
      case _ => lala
    }
  }
}
Comments