代码之家  ›  专栏  ›  技术社区  ›  Niraj Sonawane

如何通过避免手动睡眠对completeTableFuture.thenAccept()进行单元测试

  •  1
  • Niraj Sonawane  · 技术社区  · 6 年前

    单元测试中如何避免人工睡眠。 假设在下面的代码中 Process notify 处理大约需要5秒钟。所以为了完成处理,我增加了5秒的睡眠时间。

    public class ClassToTest {
    
        public ProcessService processService;
        public NotificationService notificationService;
    
        public ClassToTest(ProcessService pService ,NotificationService nService ) {
            this.notificationService=nService;
            this.processService = pService;
        }
        public CompletableFuture<Void> testMethod()
        {
              return CompletableFuture.supplyAsync(processService::process)
                            .thenAccept(notificationService::notify);
        }
    
    }
    

    有没有更好的方法来处理这个问题?

     @Test
        public void comletableFutureThenAccept() {
             CompletableFuture<Void> thenAccept = 
              sleep(6);
              assertTrue(thenAccept.isDone());  
              verify(mocknotificationService, times(1)).notify(Mockito.anystring());
        }
    
    1 回复  |  直到 6 年前
        1
  •  4
  •   Holger    6 年前

    通常,您希望测试一个底层操作是否以预期的结果完成,是否具有预期的副作用,或者至少在不引发异常的情况下完成。这可以很容易做到

    @Test
    public void comletableFutureThenAccept() {
          CompletableFuture<Void> future = someMethod();
          future.join();
          /* check for class under test to have the desired state */
    }
    

    join() 将等待完成并返回结果(如果 Void ,如果未来异常完成,则抛出异常。

    如果完成某个时间实际上是测试的一部分,只需使用

    @Test(timeout = 5000)
    public void comletableFutureThenAccept() {
          CompletableFuture<Void> future = someMethod();
          future.join();
          /* check for class under test to have the desired state */
    }
    

    在不太可能的情况下,如果您真正希望只在指定的时间内测试完成,即不关心操作是否引发异常,则可以使用

    @Test(timeout = 5000)
    public void comletableFutureThenAccept() {
          CompletableFuture<Void> future = someMethod();
          future.exceptionally(t -> null).join();
    }
    

    这用一个 null 因此,结果 连接() 不会抛出异常。所以只剩下超时。

    Java 9允许另一种选择,而不是使用JUnit Ay超时。

    @Test()
    public void comletableFutureThenAccept() {
          CompletableFuture<Void> future = someMethod().orTimeout(5, TimeUnit.SECONDS);
          future.join();
          /* check for class under test to have the desired state */
    }
    

    这样做的好处是,如果操作及时完成,但随后的验证时间较长,则不会失败。