javaakkaakka-httpakka-clusterakka-testkit

How to stub Cluster Sharding to test Akka HTTP Routes


While trying to setup a routes test for a sharding cluster in Akka I always get "system" is null:

Cannot invoke "akka.actor.ClassicActorSystemProvider.classicSystem()" because "system" is null

Here's my test, based on akka samples:

public class WeatherRoutesTest extends JUnitRouteTest {

    private static final String configuration = """
            akka.actor.provider = cluster
            killrweather.routes.ask-timeout = 60s
            """;
    private static final ActorTestKit testKit = ActorTestKit.create(ConfigFactory.parseString(configuration));
    private TestRoute weatherRoute;

    @BeforeEach
    public void setup() {
        WeatherRoutes weatherRoutes = new WeatherRoutes(testKit.system());
        weatherRoute = testRoute(weatherRoutes.weather());
    }

    @AfterAll
    public static void tearDown() {
        testKit.shutdownTestKit();
    }

    @Test
    public void testWeather() {
        weatherRoute.run(HttpRequest.GET("/weather/62?type=temperature&function=average"))
                .assertStatusCode(StatusCodes.OK());
    }

}

I have tried every suggestion I could find with no success. The samples also do not include a test for this case. Can someone please help me understand how to stub a ClusterSharding? Help, hints are appreciated!


Solution

  • To create a unit test only for the routes, I'd change the WeatherRoutes class to not lookup sharding itself but take the entity ref factory as a constructor parameter and use the TestEntityRef in tests, alternatively encode the interaction with the entity/sharding in methods that can be overridden in a test version of WeatherRoutes to directly return results suitable for each test instead of actually interacting with sharding.

    It is also possible to do a more end-to-end integration test but then you have to actually form a single node cluster in the test and then use sharding like normally. Because of cluster setup such a test will be a bit slower and have more parts that could go wrong.

    It's not entirely clear to me where the actor system would be null from what you shared, but if you want to go the integration test path you'll need to figure that out first.