1
\$\begingroup\$

I am using Vert.x. I've got a single verticle for my application that looks like this

public class HttpServerVerticle extends AbstractVerticle {
    private static final String HTTP_PORT_OPTION = "http.port";

    @Override
    public void start(Future<Void> startFuture) throws Exception {
        ConfigStoreOptions resourceStore = new ConfigStoreOptions()
            .setType("file")
            .setConfig(new JsonObject().put("path", "conf/talepath-server.json"));
        ConfigRetrieverOptions options = new ConfigRetrieverOptions()
            .addStore(resourceStore);
        ConfigRetriever retriever = ConfigRetriever.create(vertx, options);
        retriever.getConfig(ar -> {
            if (ar.failed()) {
                startFuture.fail(new RuntimeException("Failed to retrieve configuration"));
            } else {
                Router router = Router.router(vertx);
                router.route("/").handler(routingContext -> {
                    HttpServerResponse response = routingContext.response();
                    response
                        .putHeader("content-type", "text/html")
                        .end("<h1>Sample Vert.x 3 application</h1>");
                });
                router.route("/api/character").handler(routingContext -> {
                    HttpServerResponse response = routingContext.response();
                    response
                        .putHeader("content-type", "application/json; charset=utf-8")
                        .end(Json.encodePrettily(new PersonCharacter("p_id", "Jack", 20)));
                });
                JsonObject config = ar.result();
                vertx.createHttpServer()
                    .requestHandler(router)
                    .listen(
                        config.getInteger(HTTP_PORT_OPTION),
                        result -> {
                            if (result.succeeded()) {
                                startFuture.complete();
                            } else {
                                startFuture.fail(result.cause());
                            }
                        });
            }
        });
    }
}

And I have two integration tests. One for REST

@ExtendWith(VertxExtension.class)
public class HttpServerRestVerticleIntegrationTest {
    private static final String ID = "p_id";
    private static final String NAME = "Jack";
    private static final int AGE = 20;
    private static final String HTTP_PORT_OPTION = "http.port";

    @BeforeAll
    static void configureRestAssured(Vertx vertx, VertxTestContext testContext) {
        ConfigStoreOptions resourceStore = new ConfigStoreOptions()
            .setType("file")
            .setConfig(new JsonObject().put("path", "conf/talepath-server.json"));
        ConfigRetrieverOptions options = new ConfigRetrieverOptions()
            .addStore(resourceStore);
        ConfigRetriever retriever = ConfigRetriever.create(vertx, options);
        retriever.getConfig(ar -> {
            if (ar.failed()) {
                testContext.failNow(new RuntimeException("Failed to retrieve configuration"));
            } else {
                JsonObject config = ar.result();
                RestAssured.baseURI = "http://localhost";
                RestAssured.port = config.getInteger(HTTP_PORT_OPTION);
            }
        });
        vertx.deployVerticle(new HttpServerVerticle(), testContext.completing());
    }

    @Test
    @DisplayName("Test GET response")
    void checkGetCharacter() {
        PersonCharacter result = get("/api/character")
            .thenReturn()
            .as(PersonCharacter.class);
        assertThat(result.getId()).isEqualTo(ID);
        assertThat(result.getName()).isEqualTo(NAME);
        assertThat(result.getAge()).isEqualTo(AGE);
    }

    @AfterAll
    static void unconfigureRestAssured() {
        RestAssured.reset();
    }
}

And one for http server

@ExtendWith(VertxExtension.class)
public class HttpServerVerticleIntegrationTest {
    private static final String HTTP_PORT_OPTION = "http.port";

    @Test
    public void startServerTest(Vertx vertx, VertxTestContext testContext) {
        ConfigStoreOptions resourceStore = new ConfigStoreOptions()
            .setType("file")
            .setConfig(new JsonObject().put("path", "conf/talepath-server.json"));
        ConfigRetrieverOptions options = new ConfigRetrieverOptions()
            .addStore(resourceStore);
        ConfigRetriever retriever = ConfigRetriever.create(vertx, options);
        retriever.getConfig(ar -> {
            if (ar.failed()) {
                testContext.failNow(new RuntimeException("Failed to retrieve configuration"));
            } else {
                JsonObject config = ar.result();
                DeploymentOptions deploymentOptions = new DeploymentOptions().setConfig(config);
                vertx.deployVerticle(new HttpServerVerticle(), deploymentOptions, testContext.succeeding(id -> {
                    WebClient webClient = WebClient.create(vertx);
                    webClient.get(config.getInteger(HTTP_PORT_OPTION), "localhost", "/")
                        .as(BodyCodec.string())
                        .send(testContext.succeeding(response -> testContext.verify(() -> {
                            assertEquals(200, response.statusCode());
                            assertTrue(response.body().length() > 0);
                            assertTrue(response.body().contains("Sample Vert.x 3 application"));
                            testContext.completeNow();})));
                }));
            }
        });
    }
}

I rely on the properties stored in src/main/resource/conf/talepath-server.json.

I have two problems.

  • I have to read properties in test and in the main application and the code for that is the same. Is there a way to it better that just introducing a method that would return retriever entity?
  • I want to split REST routing from http server verticle. I am new to Vert.x and I am not sure what is the best way to do that. Creating separate verticle and then deploy it?
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.