无法通过我的 JUnit 测试设置集群 Vert.x 环境

Can not set up clustered Vert.x environment from my JUnit test

我有一个 junit 测试,我想在其中设置集群 vert.x 环境。如果我 运行 来自 public static void main() 方法的 setUp 方法中的代码,但如果它是来自 setUp 方法的 运行,则它工作正常。
public void handle(AsyncResult<Vertx> res) 方法永远不会被调用! 为什么?

@RunWith(VertxUnitRunner.class)
public class TestMyStuff {
    private Vertx vertx;

    @Before
    public void setUp(TestContext context) throws IOException {

        ClusterManager mgr = new HazelcastClusterManager();
        VertxOptions options = new VertxOptions().setClusterManager(mgr);
        Vertx.clusteredVertx(options, new Handler<AsyncResult<Vertx>>() {
            @Override
            public void handle(AsyncResult<Vertx> res) {
                if(res.succeeded()) {
                    vertx = res.result();

                    DeploymentOptions options = new DeploymentOptions()
                            .setConfig(new JsonObject().put("http.port", 8080)
                            );
                    vertx.deployVerticle(MyWebService.class.getName(), options, context.asyncAssertSuccess());
                    System.out.println("SUCCESS");
                } else {
                    System.out.println("FAILED");
                }
            }
        });
    }

    @Test
    public void printSomething(TestContext context) {
        System.out.println("Print from method printSomething()");
    }

"Print from method printSomething()" 正在写入,但不是来自 handle() 方法的 "SUCCESS" 或 "FAILED"。

为什么它在 setUp 方法中不起作用,而在 main() 中起作用?

由于 VertX 的异步行为,测试设置不正确:

  • @Before 中的代码使用 Vertx.clusteredVertx() 以异步方式启动 VertX,但它甚至没有时间启动 VertX
  • printSomething() 方法在 clusteredVertx() 调用之后立即启动(没有 运行 VertX),测试本身立即结束,因此 JUnit 停止了整个测试过程,杀死甚至没有启动的 VertX

我前段时间也遇到过这个问题,请问遇到这种情况怎么办?

您应该正确设置 VertX 并等待您的测试方法完成设置。我可以使用 Awaitility (https://github.com/jayway/awaitility).

等候机制来完成此操作

要点

  • 设置一个变量等待vertx的设置
  • 在 clusteredVertx 调用的处理程序中,将变量设置为 true
  • 最后,等待在测试方法中设置这个变量

@RunWith(VertxUnitRunner.class) 
public class TestMyStuff {
   private Vertx vertx;

   final AtomicBoolean loaded = new AtomicBoolean(false);

   @Before
   public void setUp(TestContext context) throws IOException {
    ClusterManager mgr = new HazelcastClusterManager();
    VertxOptions options = new VertxOptions().setClusterManager(mgr);
    Vertx.clusteredVertx(options, new Handler<AsyncResult<Vertx>>() {
        @Override
        public void handle(AsyncResult<Vertx> res) {
            if (res.succeeded()) {
                vertx = res.result();

                DeploymentOptions options = new DeploymentOptions()
                        .setConfig(new JsonObject().put("http.port", 8080)
                        );
                //vertx.deployVerticle(MyWebService.class.getName(), options, context.asyncAssertSuccess());
                System.out.println("SUCCESS");
                loaded.set(true);
            } else {
                System.out.println("FAILED");
            }
         }
       });
   }

   @Test
   public void printSomething(TestContext context) {


    Awaitility.waitAtMost(Duration.ONE_MINUTE).await().untilTrue(loaded);
    System.out.println("Print from method printSomething()");
   }
}

我希望这有助于理解要点,这样您也可以找到任何其他解决方法!

VertX 确实有自己的功能来处理多线程和异步请求。

只需在您的测试函数中使用 Async class:

   @Test
   public void printSomething(TestContext context) {
        Async async = context.async();
        System.out.println("Print from method printSomething()");
        async.complete();     
   }

希望对以后的body有所帮助。