java - Integration tests for akka http endpoints - Stack Overflow

I have an akka based application, and it has Application.java file which has structure like what we hav

I have an akka based application, and it has Application.java file which has structure like what we have defined here.

Now I want to write integration tests for akka http endpoints in this application, as discussed here.

It says that I need to launch application in @BeforeClass method.

So how do I start application. I guess merely calling main function wont work as it would block the program and tests would never hit.

I have an akka based application, and it has Application.java file which has structure like what we have defined here.

Now I want to write integration tests for akka http endpoints in this application, as discussed here.

It says that I need to launch application in @BeforeClass method.

So how do I start application. I guess merely calling main function wont work as it would block the program and tests would never hit.

Share Improve this question edited Feb 21 at 4:07 Gastón Schabas 3,7111 gold badge14 silver badges22 bronze badges asked Feb 21 at 3:25 MandroidMandroid 7,56015 gold badges86 silver badges183 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

I understand that you want to start a real http server for your integration test. You could extract the logic inside main method to another one and return the ActorSystem created.

    public static ActorSystem<NotUsed> startActorSystem() {
        //#server-bootstrapping
        Behavior<NotUsed> rootBehavior = Behaviors.setup(context -> {
            ActorRef<UserRegistry.Command> userRegistryActor =
                    context.spawn(UserRegistry.create(), "UserRegistry");

            UserRoutes userRoutes = new UserRoutes(context.getSystem(), userRegistryActor);
            startHttpServer(userRoutes.userRoutes(), context.getSystem());

            return Behaviors.empty();
        });

        // boot up server using the route as defined below
        return ActorSystem.create(rootBehavior, "HelloAkkaHttpServer");
        //#server-bootstrapping
    }

Then, you can start the real server invoking that method

var actorSystem = actorSystem = QuickstartApp.startActorSystem();

Now you can send real http requests to the server instead of testing the routes isolated.

Your new test should look like the following

import akka.NotUsed;
import akka.actor.typed.ActorSystem;
import akka.http.javadsl.Http;
import akka.http.javadsl.marshallers.jackson.Jackson;
import akka.http.javadsl.model.HttpRequest;
import akka.http.javadsl.model.MediaTypes;
import .junit.*;
import .junit.runners.MethodSorters;

import java.util.concurrent.ExecutionException;

import static .junit.Assert.assertEquals;
import static .junit.Assert.assertTrue;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class UserRoutesIntegrationTest {

    private static ActorSystem<NotUsed> actorSystem;

    @BeforeClass
    public static void beforeClass() {
        // ---------------------------
        // START THE REAL SERVER HERE
        // ---------------------------
        actorSystem = QuickstartApp.startActorSystem();
    }

    @AfterClass
    public static void afterClass() {
        // ------------------------------
        // SHUT DOWN THE REAL SERVER HERE
        // ------------------------------
        actorSystem.terminate();
    }

    @Test
    public void test1NoUsers() throws ExecutionException, InterruptedException {
        // ------------------------------------------
        // SEND REAL HTTP REQUEST TO REAL HTTP SERVER
        // ------------------------------------------
        var responseCompletionStage = Http
            .get(actorSystem)
            .singleRequest(HttpRequest.GET("http://localhost:8080/users"));
        // ---------------------------
        // UNMARSHAL THE HTTP RESPONSE
        // ---------------------------
        var usersCompletionStage = responseCompletionStage
                .thenCompose(response -> Jackson.unmarshaller(UserRegistry.Users.class).unmarshal(response.entity(), actorSystem));
        var users = usersCompletionStage.toCompletableFuture().get();
        // ----------
        // ASSERTIONS
        // ----------
        assertTrue(users.users().isEmpty());
    }

    @Test
    public void test2HandlePOST() throws ExecutionException, InterruptedException {
        var responseCompletionStage = Http
            .get(actorSystem)
            .singleRequest(
                HttpRequest
                    .POST("http://localhost:8080/users")
                    .withEntity(
                        MediaTypes.APPLICATION_JSON.toContentType(),
                        """
                                {
                                    "name": "Kapi",
                                    "age": 42,
                                    "countryOfResidence": "jp"
                                }
                            """
                    )
                );

        var actionPerformedCompletionStage = responseCompletionStage
                .thenCompose(response -> Jackson
                        .unmarshaller(UserRegistry.ActionPerformed.class)
                        .unmarshal(response.entity(), actorSystem));
        var actionPerformed = actionPerformedCompletionStage.toCompletableFuture().get();
        assertEquals("User Kapi created.", actionPerformed.description());
    }

    @Test
    public void test3Remove() throws ExecutionException, InterruptedException {
        var responseCompletionStage = Http
                .get(actorSystem)
                .singleRequest(HttpRequest.DELETE("http://localhost:8080/users/Kapi"));
        var actionPerformedCompletionStage = responseCompletionStage
                .thenCompose(response -> Jackson
                        .unmarshaller(UserRegistry.ActionPerformed.class)
                        .unmarshal(response.entity(), actorSystem));
        var actionPerformed = actionPerformedCompletionStage.toCompletableFuture().get();
        assertEquals("User Kapi deleted.", actionPerformed.description());
    }
}

This is a dummy example of an integration test because you only need to start the http server. In case you need a database, a message queue or even another real server running in a docker container you could use something like Java Testcontainers.

Have also in mind that you are hardcoding many things in your main class, such as the port or interface. It could be a good idea to do some refactor and receive some values or a Config object by param to make your tests more flexibles

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745168474a4614777.html

相关推荐

  • java - Integration tests for akka http endpoints - Stack Overflow

    I have an akka based application, and it has Application.java file which has structure like what we hav

    7小时前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信