介绍

Vertx-junit5该模块为使用 JUnit 5 编写 Vert.x 测试提供集成和支持

1. maven项目依赖

<dependencies>
	<dependency>
		<groupId>io.vertx</groupId>
		<artifactId>vertx-web</artifactId>
	</dependency>
	<dependency>
		<groupId>io.vertx</groupId>
		<artifactId>vertx-config-yaml</artifactId>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-databind</artifactId>
	</dependency>
	<dependency>
		<groupId>com.lance.common</groupId>
		<artifactId>vertx-common-core</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</dependency>
	 <!-- Test -->
	<dependency>
		<groupId>io.vertx</groupId>
		<artifactId>vertx-junit5</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>

2.YAML文件配置

server:
  port: 18002

3.启动加载配置文件, 并放入到config中去

public class UnitApplication {

  public static void main(String[] args) {
    Vertx vertx = Vertx.vertx();
    ConfigRetriever retriever = readYaml(vertx);

    retriever.getConfig(json -> {
      DeploymentOptions options = new DeploymentOptions().setConfig(json.result());
      vertx.deployVerticle(MainApp.class.getName(), options);
    });
  }

  private static ConfigRetriever readYaml(Vertx vertx) {
    ConfigStoreOptions store = new ConfigStoreOptions()
        .setType("file")
        .setFormat("yaml")
        .setOptional(true)
        .setConfig(new JsonObject().put("path", "application.yaml"));

    return ConfigRetriever.create(vertx, new ConfigRetrieverOptions().addStore(store));
  }
}

4.Vertx http client单元测试

Slf4j
@ExtendWith(VertxExtension.class)
class WebRequestTests {
  private final Vertx vertx = Vertx.vertx();

  /**
   * test vertx server
   */
  @Test
  @Disabled
  void suite() {
    vertx.createHttpServer()
        .requestHandler(req -> req.response().end("Ok"))
        .listen(16969, ar -> {
          log.info("===> vertx start: {}", ar.succeeded());
        });
  }

  /**
   * 1.允许等待其他线程中的操作以通知完成, 类似java中promise对象
   * 2.支持接收断言失败以将测试标记为失败
   */
  @Test
  @Disabled
  void asyncContext() throws Throwable {
    VertxTestContext testContext = new VertxTestContext();

    vertx.createHttpServer()
        .requestHandler(req -> req.response().end())
        .listen(16969)
        .onComplete(testContext.succeedingThenComplete());
    //.onComplete(testContext.failingThenComplete());

    Assertions.assertTrue(testContext.awaitCompletion(5, TimeUnit.SECONDS));
    if (testContext.failed()) {
      throw testContext.causeOfFailure();
    }
  }

  /**
   * Test http client
   */
  @Test
  @Disabled
  void httpClient() throws Exception {
    HttpClient client = vertx.createHttpClient();
    VertxTestContext testContext = new VertxTestContext();

    client.request(HttpMethod.GET, 18002, "127.0.0.1", "/user/info/2")
        .compose(req -> req.send().compose(HttpClientResponse::body))
        .onComplete(testContext.succeeding(buffer -> testContext.verify(() -> {
          JsonObject jsonObject = buffer.toJsonObject();
          log.info("===>Response body: {}", jsonObject);
          Assertions.assertEquals(jsonObject.getString("code"), HttpResponseStatus.OK.reasonPhrase());
          testContext.completeNow();
        }))).onFailure(event -> log.error("===>fail: ", event.getCause()));

    boolean awaitResult = testContext.awaitCompletion(30, TimeUnit.SECONDS);
    log.info("===>Await: {}", awaitResult);
  }

  /**
   * 只需调用即可将许多测试标记为通过completeNow在执行的某个时间点。话虽如此,在许多情况下,测试的成功取决于要验证的不同异步部分。
   */
  @Test
  @Disabled
  void checkpoint() {
    int port = 9001;
    VertxTestContext testContext = new VertxTestContext();
    Checkpoint serverStarted = testContext.checkpoint();
    Checkpoint requestsServed = testContext.checkpoint(10);
    Checkpoint responsesReceived = testContext.checkpoint(10);

    vertx.createHttpServer()
        .requestHandler(req -> {
          req.response().end("success");
          requestsServed.flag();
        })
        .listen(port)
        .onComplete(testContext.succeeding(httpServer -> {
              serverStarted.flag();

              HttpClient client = vertx.createHttpClient();
              for (int i = 0; i < 10; i++) {
                client.request(HttpMethod.GET, port, "localhost", "/")
                    .compose(req -> req.send().compose(HttpClientResponse::body))
                    .onComplete(testContext.succeeding(buffer -> testContext.verify(() -> {
                          Assertions.assertEquals("success", buffer.toString());
                          responsesReceived.flag();
                        }))
                    );
              }
            })
        );
  }
}

5.Vertx test context单元测试

@Slf4j
@ExtendWith(VertxExtension.class)
class VertxExtensionTests {
  private final int port = 9000;

  @BeforeEach
  void init(Vertx vertx, VertxTestContext testContext) {
    vertx.deployVerticle(new HttpServerVertical(), testContext.succeedingThenComplete());
  }

  @AfterEach
  public void after(Vertx vertx) {
    log.info("===>Vertx close.");
    vertx.close();
  }

  /**
   * 连续测试3次
   * repetition 1 of 3
   * repetition 2 of 3
   * repetition 3 of 3
   */
  @Disabled
  @RepeatedTest(3)
  void request3Times(Vertx vertx, VertxTestContext testContext) {
    HttpClient client = vertx.createHttpClient();
    client.request(HttpMethod.GET, port, "localhost", "/")
        .compose(req -> req.send().compose(HttpClientResponse::body))
        .onComplete(testContext.succeeding(buffer -> testContext.verify(() -> {
          log.info("===>Response result: {}", buffer.toString());
          testContext.completeNow();
        })));
  }

  @Test
  @Timeout(value = 100, unit = TimeUnit.MILLISECONDS)
  void timeout(Vertx vertx, VertxTestContext testContext) {
    HttpClient client = vertx.createHttpClient();
    client.request(HttpMethod.GET, port, "localhost", "/")
        .compose(req -> req.send().compose(HttpClientResponse::body))
        .onComplete(testContext.succeeding(buffer -> testContext.verify(() -> {
          Thread.sleep(5000L);
          log.info("===>Response timeout result: {}", buffer.toString());
          testContext.completeNow();
        })));
  }

  /**
   * 单服务测试
   */
  @Test
  @Disabled
  void httpServerResponse(Vertx vertx, VertxTestContext testContext) {
    vertx.deployVerticle(new HttpServerVertical(), testContext.succeeding(id -> {

      HttpClient client = vertx.createHttpClient();
      client.request(HttpMethod.GET, port, "localhost", "/")
          .compose(req -> req.send().compose(HttpClientResponse::body))
          .onComplete(testContext.succeeding(buffer -> testContext.verify(() -> {
            log.info("===>Response result: {}", buffer.toString());
            Assertions.assertEquals(buffer.toString(), "success");
            testContext.completeNow();
          })));
    }));
  }

  class HttpServerVertical extends AbstractVerticle {
    @Override
    public void start() throws Exception {
      vertx.createHttpServer()
          .requestHandler(req -> {
            req.response().end("success");
          })
          .listen(port).onComplete(event -> {
            if (event.succeeded()) {
              log.info("===>Start [{}] success!", port);
              return;
            }

            log.error("===>Start fail: ", event.cause());
          });
    }
  }
}

6.项目完整地址

Vertx之Junit单元测试 Github 地址

Vertx之Junit单元测试 Gitee 地址

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐