score:0
To mock an actor is easier through the TestActorRef. You can use this code :
static ActorSystem system = ActorSystem.create();
static Props propsSome = Props.create(MockedResultActor.class);
TestActorRef<MockedResultActor> refMockedResultActor= TestActorRef.create(
system, propsSome, "testA");
// Mocking an actor class and returning our reference actor
PowerMockito.mockStatic(ClassToBeMocked.class);
Mockito.when(ClassToBeMocked.getToBeMockedMethod())
.thenReturn(refMockedResultActor);
Note: ClassToBeMocked--Its a class you want to mock. MockedResultActor -- Its a class you want to return after mocking. This can be run using JunitTest after implementing basic configuration of mocking in your class. Code given here is specific to akka actor in java only.
score:1
So I'm probably not understanding the question but you probably don't want to mock an actor as the purpose of mocking is to replace something like a dao with a test copy that has expectations of invocation - actor doesn't really fit the bill as it's something you extend rather than a dependency - mocking really only applies to real dependencies.
TestActorRef specifically gives you access to the underlying actor - in most normal circumstances you can only send messages to an actor and not invoke anything directly on it. TestActoRef removes this limitation by allowing you to access your real true extension of Actor instead of just the ActorRef that you can only ! or ? against (send or ask).
I'm a scala dev so the insight is hopefully agnostic. I don't know the java api specifically but it shouldn't matter.
My recommendation is to get the real Actor object via actor ref and just test the method or figure out some way to get test coverage through real messages.
score:2
I have no experience in using Akka with Java, but I guess the solution for this I use in Scala can also apply to Java. There is no need at all to mock anything. In Java mocking is sometimes useful for testing, but my personal experience/opinion is that whenever you need PowerMock you're doing something wrong.
Here's how I try to test using Akka:
In Scala I use a trait (aka interface) in which the actor methods are defined.
trait ToBeTested {
def getHelloMessage(msg: String, replyTarget: ActorRef): String =
replyTarget ! s"Hello $msg"
}
This way, this functionality can be unit tested very easy. For the real actor I try to stick to implement the receive method only.
class ToBeTestedActor extends Actor with ToBeTested {
def receive: Receive = {
case msg: String => getHelloMessage(msg, sender())
}
}
Then when testing the actor, you can override the getHelloMessage implementation to do whatever you want.
class ToBeTestedActorTest extends TestKit(ActorSystem("toBeTested") with .... {
trait MyToBeTested extends ToBeTested {
// do something predictable for testing or defer to a TestProbe which you can
// either define globally in the test class or provide one in a constructor.
override def getHelloMessage(msg: String, replyTarget: ActorRef): String = ???
}
val toBeTestedActor = TestActorRef(Probe(new ToBeTestedActor with MyToBeTested))
// ... (test cases)
}
In Java you can do pretty much the same thing. Since Java 8 you can provide default method implementations in interfaces, which you can override in a sub-interface for testing. Another way would be to subclass the actor in your test to override some methods to provide predictable behaviour.
// An easy unit testable interface
public interface ToBeTested {
public ActorRef self();
default public void getHelloMessage(String msg, ActorRef replyTarget) {
replyTarget.tell(String.format("Hello %s", msg), self());
}
}
public class ToBeTestedActor extends UntypedActor implements ToBeTested {
// self() already implemented by Actor class
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof String) {
getHelloMessage((String)message, getSender());
}
}
}
public class ToBeTestedActorTest {
@Test
public void test() throws Exception {
ActorSystem system = ActorSystem.create();
TestActorRef<Actor> testActorRef = TestActorRef.create(system, Props.create(TestActor.class));
Future<Object> response = Patterns.ask(testActorRef, "World", 1000);
assertThat(response.isCompleted(), is(true));
assertThat(Await.result(response, Duration.Zero()), is("Test"));
}
// Override interface when using Java 8
interface DummyToBeTested extends ToBeTested {
@Override
default void getHelloMessage(String msg, ActorRef replyTarget) {
assertThat(msg, is("World"));
replyTarget.tell("Test", self());
}
}
// extend ToBeTestedActor with dummy interface
static class TestActor extends ToBeTestedActor implements DummyToBeTested {}
// Or (pre Java 8) extend the ToBeTestedActor directly
// static class TestActor extends ToBeTestedActor {
// @Override
// public void getHelloMessage(String msg, ActorRef replyTarget) {
// replyTarget.tell("Test", self());
// }
// }
}
score:10
Akka has a class AutoPilot
that is basically a general mock for actors, with the ability to respond to messages and assert that messages were sent.
http://doc.akka.io/docs/akka/snapshot/java/testing.html
Here's the java example for that page. You create a probe, set an auto-pilot that can respond to messages, and get an ActorRef
from it that you can substitute in for your real actor.
new JavaTestKit(system) {{
final JavaTestKit probe = new JavaTestKit(system);
// install auto-pilot
probe.setAutoPilot(new TestActor.AutoPilot() {
public AutoPilot run(ActorRef sender, Object msg) {
sender.tell(msg, ActorRef.noSender());
return noAutoPilot();
}
});
// first one is replied to directly ...
probe.getRef().tell("hello", getRef());
expectMsgEquals("hello");
// ... but then the auto-pilot switched itself off
probe.getRef().tell("world", getRef());
expectNoMsg();
}};
Source: stackoverflow.com
Related Query
- How to test Akka Actor functionality by mocking one or more methods in it
- How to test that Akka actor was created in Scala
- How do I test an Akka actor that sends a message to another actor?
- How to mock an Akka Actor to Unit Test a class?
- Specs2: how to test a class with more than one injected dependency?
- How to unit test an Akka actor that sends a message to itself, without using Thread.sleep
- How do I unit test an akka Actor synchronously?
- How to test Akka actor that spawn child actors at runtime?
- How to test an untyped actor deployment from a typed context using akka BehaviorTestKit?
- How to restrict the akka actor to do one job at a time
- How can I get the name of an Akka actor from within the actor itself?
- Akka - How many instances of an actor should you create?
- How does one log Akka HTTP client requests
- How to get Akka actor by name as an ActorRef?
- How to test methods that return Future?
- How to wait for Akka actor system to terminate?
- How to test client-side Akka HTTP
- akka: how to test that an actor was stopped
- How to select akka actor with actorSelection?
- How can one verify messages sent to self are delivered when testing Akka actors?
- Scala, how to read more than one integer in one line in and get them in one variable each?
- Scala: How to test methods that call System.exit()?
- Akka TCP client: How can I send a message over TCP using akka actor
- Play Framework 2 scala specs2 mockito, how do I write a mocking unit test
- How do I setup akka Actor fault tolerance?
- Akka HTTP Websocket, how to identify connections inside of actor
- How to test methods based on Salat with ScalaTest
- Akka Actor how to only process the latest message
- How to start a Scala akka actor
- Scala: how to split using more than one delimiter
More Query from same tag
- sbt-docker difference between add and addRaw
- Private Chat Application using Play 2.3 Websocket
- Multiple queries in the same view
- ScalaPlay > 2.6 how to access POST requests while faking a trivial server in tests
- Sorting by DateTime in Slick
- Using regex parser within a JavaTokensParser subclass
- incorrect JARs for Casbah in Scala?
- Scala lists "var" usage
- What's the type of the input parameter of user-defined function to accept nested JSON structs with arrays?
- Restructring the textfile based on pattern in the file
- Create SOAP XML REQUEST from selected dataframe columns in Scala
- Parse signed number from hex using BigInt
- Write a General Filter Type Class?
- How to add new SBT module in intelliJ?
- Append a row to a pair RDD in spark
- Kafka Producer producer.send very slow
- how to convert List[java.util.Map] to List[Map]
- splitAt '-' in scala
- Spark: remove all duplicated lines
- Akka teskit.spawn to return ActorSystem
- Fetch Spark dataframe column list
- Whats the difference between RoundRobinPool and RoundRobinRouter
- efficiently implementing takeByKey for spark
- Remove all records which are duplicate in spark dataframe
- Scala type inference limitations
- How to set and save metadata of mp3 file using mp3agic in Scala
- Comet JSON push to javascript
- Polymorphic return type by using TypeTag in Scala
- Trying to get a list with the Typesafe config library
- Automatically include javascript in Scaladoc using SBT