akka-test-junit

Useful JUnit hooks for testing Akka actors

License

License

Apache License, Version 2.0
Categories

Categories

JUnit Unit Testing Akka Container Microservices Reactive libraries
GroupId

GroupId

org.zapodot
ArtifactId

ArtifactId

akka-test-junit
Last Version

Last Version

2.0.0
Release Date

Release Date

Type

Type

jar
Description

Description

akka-test-junit
Useful JUnit hooks for testing Akka actors
Project URL

Project URL

https://github.com/zapodot/akka-test-junit
Source Code Management

Source Code Management

https://github.com/zapodot/akka-test-junit

Download akka-test-junit

How to add to project

<!-- https://jarcasting.com/artifacts/org.zapodot/akka-test-junit/ -->
<dependency>
    <groupId>org.zapodot</groupId>
    <artifactId>akka-test-junit</artifactId>
    <version>2.0.0</version>
</dependency>
// https://jarcasting.com/artifacts/org.zapodot/akka-test-junit/
implementation 'org.zapodot:akka-test-junit:2.0.0'
// https://jarcasting.com/artifacts/org.zapodot/akka-test-junit/
implementation ("org.zapodot:akka-test-junit:2.0.0")
'org.zapodot:akka-test-junit:jar:2.0.0'
<dependency org="org.zapodot" name="akka-test-junit" rev="2.0.0">
  <artifact name="akka-test-junit" type="jar" />
</dependency>
@Grapes(
@Grab(group='org.zapodot', module='akka-test-junit', version='2.0.0')
)
libraryDependencies += "org.zapodot" % "akka-test-junit" % "2.0.0"
[org.zapodot/akka-test-junit "2.0.0"]

Dependencies

compile (5)

Group / Artifact Type Version
junit : junit jar 4.12
org.slf4j : slf4j-api jar 1.7.25
com.typesafe.akka : akka-actor_2.11 jar 2.5.11
com.typesafe.akka : akka-testkit_2.11 jar 2.5.11
com.typesafe.akka : akka-slf4j_2.11 Optional jar 2.5.11

runtime (1)

Group / Artifact Type Version
com.github.michaelpisula : akka-persistence-inmemory_2.11 Optional jar 0.2.1

test (1)

Group / Artifact Type Version
org.slf4j : slf4j-simple jar 1.7.25

Project Modules

There are no modules declared in this project.

Akka Test JUNIT

Flattr this git repo Build Status Coverage Status Maven Central License: Apache 2 Libraries.io for GitHub

Provides a JUnit rule for controlled testing of Akka actors using JUnit.

Tested with Akka 2.5.11 and JUnit 4.12. This tool, including the source code is made available under an Apache 2.0 license.

Add dependency

As this library is distributed through the Sonatype OSS repository, it should be easy to add it to your project

Maven

<dependency>
    <groupId>org.zapodot</groupId>
    <artifactId>akka-test-junit</artifactId>
    <version>2.0.0</version>
    <scope>test</scope>
</dependency>

SBT

libraryDependencies += "org.zapodot" % "akka-test-junit" % "2.0.0"

Gradle

compile 'org.zapodot:akka-test-junit:2.0.0'

Example

The ActorSystemRule may be used either as a @Rule (invoked around test methods) or as a @ClassRule (invoked before/after the TestClass)

As a @Rule

public class SimpleAkkaTest {

    @Rule
    public ActorSystemRule actorSystemRule = new ActorSystemRuleBuilder().setName(getClass().getSimpleName()).build();

    @Test
    public void testRuleUsingASingleActor()  {
        final TestActorRef<SimpleActor> actorTestActorRef = TestActorRef.create(actorSystemRule.system(),
                                                                          Props.create(SimpleActor.class));
        final String message = "test";
        actorTestActorRef.tell(message, ActorRef.noSender());
        assertEquals(message, actorTestActorRef.underlyingActor().received.peek());
        
        // Use the testKit() to get an instance of JavaTestKit directly
        // In this example EchoActor simply sends the message to the designated sender actor
        final JavaTestKit testKit = actorSystemRule.testKit();
        final Props simpleActorProps = Props.create(EchoActor.class);
        final ActorRef simpleActor = actorSystemRule.system().actorOf(simpleActorProps);
        simpleActor.tell("A great message", testKit.getTestActor()); // Use testActor as sender
        testKit.expectMsgEquals(FiniteDuration.apply(1L, TimeUnit.SECONDS), "A great message");
           

    }

        
}

As a @ClassRule

public class SimpleAkkaTest {

    // ClassRules must be instantiated as public static fields on the test class
    @ClassRule
    public static ActorSystemRule actorSystemRule = ActorSystemRule.builder().setName(getClass().getSimpleName()).build();

    @Test
    public void testRuleUsingASingleActor() {
        final TestActorRef<SimpleActor> actorTestActorRef = TestActorRef.create(actorSystemRule.system(),
                                                                          Props.create(SimpleActor.class));
        final String message = "test";
        actorTestActorRef.tell(message, ActorRef.noSender());
        assertEquals(message, actorTestActorRef.underlyingActor().received.peek());

    }
    
    @Test
    public void testAnotherThing() {
        final TestActorRef<SimpleActor> actorTestActorRef = TestActorRef.create(actorSystemRule.system(),
                                                                                  Props.create(SimpleActor.class));
        // Will use the same actorSystem instance as in the previous test. NB! Be aware of JUnit's ordering rules                                                                         
    }
}

With event logging enabled (version >= 1.1.0)

@Rule
public ActorSystemRule actorSystemWithEventLoggerEnabled = ActorSystemRule.builder()
                                                        .enableEventLogging()
                                                        .setName(getClass().getSimpleName())
                                                        .build();

With event test listener enabled(version >= 1.1.0)

@Rule
public ActorSystemRule actorSystemRule = ActorSystemRule.builder()
                                                       .setName(getClass().getSimpleName())
                                                       .setConfigFromString("akka.loglevel = DEBUG")
                                                       .enableEventTestListener()
                                                       .build();

@Test
public void testEventFilterEnabled() throws Exception {
   new JavaTestKit(actorSystemRule.system()) {{
       final ActorRef loggingActor = getSystem().actorOf(Props.create(LoggingActor.class), "loggingActor");
       Integer result = new EventFilter<Integer>(Logging.Info.class) {
           @Override
           protected Integer run() {

               loggingActor.tell(LoggingActor.INFO_MESSAGE, ActorRef.noSender());
               return 1;
           }
       }.from(loggingActor.path().toString()).occurrences(1).exec();
       assertEquals(1, result.intValue());
   }};

}

With custom configuration (version >= 1.1.0)

public class SimpleAkkaTest {

    @Rule
    public ActorSystemRule actorSystemRule = ActorSystemRule.builder().setName("test-system").setConfigFromString(
            "akka {\n"
            + "    loggers = [\"akka.event.slf4j.Slf4jLogger\"]\n"
            + "    loglevel = DEBUG\n"
            + "}").build();

    @Test
    public void testRuleUsingASingleActor() throws Exception {
        final TestActorRef<SimpleActor> actorTestActorRef = TestActorRef.create(actorSystemRule.system(),
                                                                          Props.create(SimpleActor.class));
        final String message = "test";
        actorTestActorRef.tell(message, ActorRef.noSender());
        assertEquals(message, actorTestActorRef.underlyingActor().received.peek());

    }
}

Changelog

  • Version 2.0.0: Akka 2.5.0 support - support for previous versions are dropped. Java baseline is 1.8
  • Version 1.3.0: Verifies that the ActorSystem is indeed properly shutdown. Allows a shutdown timeout to be set
  • Version 1.2.0: Add a new testKit() method that to create a JavaTestKit
  • Version 1.1.1: Fixed a bug in ActorSystemRuleBuilder that replaced the configuration instead of added to it
  • Version 1.1: Added the ActorSystemRuleBuilder and the ability to specify configuration and/or enable logging for the actor system
  • Version 1.0: First release

Limitations

A few words of caution when using @ClassRule:

  • JUnit might not run the tests in the order you predicted. Check JUnit execution ordering.
  • If you name your actors be aware the Akka expects actor names to be unique within the same actor system

Versions

Version
2.0.0
1.3.0
1.2.0
1.1.2
1.1.1
1.1.0
1.0.0