How can I test a Subscriber's receive method in Akka Cluster?

377 views Asked by At

I have the following Subscriber abstract base class:

abstract class Subscriber(topics: Seq[String]) extends Actor with ActorLogging {
  import DistributedPubSubMediator.{ Subscribe, SubscribeAck }

  val mediator = DistributedPubSub(context.system).mediator

  // subscribe to each topic
  topics.foreach{mediator ! Subscribe(_, self)}

  def receive = {
    case SubscribeAck(Subscribe(name, None, `self`)) ⇒
      log.info(s"Subscribing to $name")
  }
}

And I'd like to test that it receives messages that are published to topics to which a subclass is subscribed. Some simple pseudocode that demonstrates that is the following:

val topic = "foo"

class FooSubscriber extends Subscriber(Seq(topic))

val fooSubActor = system.actorOf(Props[FooSubscriber])    
val mediator = DistributedPubSub(system).mediator
val msg = "This is a string"

// Publish the msg to the "foo" topic.
mediator ! Publish(topic, msg)

fooSubActor.expectMsg(msg)

The only way I know to make assertions about messages that specific actors receive is by way of TestProbe, but I don't know how I could make a TestProbe extend my class.

Typically the Akka docs have loads of sample code with associated test suites, but I couldn't find anything in the Akka Cluster docs related to testing the receive method.

Does anyone have suggestions?

1

There are 1 answers

4
emilianogc On

This is a textbook example of where Dependency Injection helps with testability.

If you receive the mediator for DistPubSub in the Subscriber constructor instead of directly asking for it you can just test the Suscriber actor in isolation, without the need to use the DistPubSub as part of your test fixture.