Java/Junit 中的异步单元测试 - 一个非常简单但不成功的示例

Mar*_*lli 5 java junit unit-testing asynchronous

在 JavaScript 中(例如使用 Mocha),我可以编写异步单元测试,在最终回调中断言内容。

这是通过将令牌函数(通常称为done)作为参数传递给测试方法来完成的。

当调用该函数时,测试框架知道测试已完成。

例如:

  it('succeeds or fails in the last callback', function(done) {

      var deferred = Q.defer();
      setTimeout(function() { deferred.resolve('expected'); }, 500);

      deferred.promise.then(function(result) {
          assertEquals('expected', result);
          done();  // end of test
      });

  });
Run Code Online (Sandbox Code Playgroud)

我发现 Junit 不适合这种情况。首先,测试方法无法处理参数,无论如何,如果我尝试例如:

  @Test
  public void testAssertionInsideContinuation() {

      Long now = System.currentTimeMillis();
      System.out.println("TimeMillis=" + now);

      CompletableFuture fut = new CompletableFuture();

      Executors.newScheduledThreadPool(1)
          .schedule(() -> { fut.complete("whatever"); }, 500, TimeUnit.MILLISECONDS);

      fut.thenRun(() -> {
          long then = System.currentTimeMillis();
          System.out.println("TimeMillis=" + then);
          assertTrue(then - now >= 500);
      });
  }
Run Code Online (Sandbox Code Playgroud)

第二个println不会被执行,因为测试很早就已经完成了。

如果我作弊并Thread.currentThread().sleep(500);在测试方法的末尾添加 a ,那么 future 有机会完成,并且执行断言 + 第二个打印输出。

我有几个问题:

  • 最简单的 Java 设置是什么,我可以在其中验证回调/延续/thenables 内的断言(无论你喜欢如何称呼它们),而不必阻止测试?
  • 我必须完全放弃 Junit 吗?
  • 是否有主流测试框架(TestNG,也许?)允许以这种方式编写异步单元测试?

顺便说一句,如果有人能建议我一种编写这个 Java 示例测试而不诉诸ScheduledFuture's 的方法,我也将不胜感激。我尝试过一些实验,但supplyAsync没有真正确定解决方案。

Fed*_*ore 3

测试时,CompletableFuture您需要等待所有步骤完成。

代替 a Thread.sleep,添加最后一个fut.join()