Spock mocks for Akka's ActorRef
Asked Answered
P

2

9

I've tried to make an Spock test for a class, where i need to check that it sends a message to actor (say statActor). I know that Akka have special library for integration test, but seems that it's too much for very simple test. So, i've tried:

setup:
def myActor = Mock(ActorRef)
myService.statActor = myActor
when:
myService.startStats()
then:
1 * myActor.tell(_)

Target method looks like:

void startStats() {
    Date x = null
    // prepare some data, fill x with required value
    this.statActor.tell(x)
}

I thought that Spock will create mock with a method tell. But after running this test i'm getting:

java.lang.ClassCastException: akka.actor.ActorRef$$EnhancerByCGLIB$$80b97938 cannot be cast to akka.actor.ScalaActorRef
    at akka.actor.ActorRef.tell(ActorRef.scala:95)
    at com.example.MyService.startStats(MyService.groovy:32)

Why it's calling real ActorRef implementation? Some kind of incompatibility with Scala? Is there any way to make mock for such class?

Piquant answered 3/6, 2012 at 8:41 Comment(3)
"but seems that it's too much for very simple test" <-- may I ask how this conclusion is made, especially considering that the mocking you've tried didn't work out?Cull
@ViktorKlang because one line def actor = Mock(ActorRef) is less that few dozen of lines required for testkit. I mean it can make mock for other objects, works fine and really easy to usePiquant
@paradigmatic yes, i know. probably I'm asking hard questions, but what can I do here? :(Piquant
P
20

The only supported way to mock an ActorRef is by creating a TestProbe:

// "system" is an ActorSystem
final TestProbe probe = TestProbe.apply(system);
final ActorRef mock = probe.ref;

It does not get easier or simpler than this.

Pirozzo answered 4/6, 2012 at 5:48 Comment(5)
Thanks. How I can test that .tell() is called for this actor, with a value that i can test as well?Piquant
There plenty of methods for asserting message reception on a probe, listed on doc.akka.io/api/akka/2.0/akka/testkit/TestProbe.htmlAcarology
Oh, I was sure that it's the same as TestActorRefPiquant
@Roland Kuhn Actually i've asked about using it with Spock. As I understand, you mean that there is not way to use standard Spock mocks for Akka, right?Piquant
@Igor: If you want to write your own testkit for Akka, feel free.Cull
S
2

In specs2 you can do:

val mockedActorRef = spy(TestProbe().ref)

Then use it as normal.

Ss answered 2/10, 2015 at 1:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.