How to use JUnit to test asynchronous processes

前端 未结 18 1632
小蘑菇
小蘑菇 2020-11-29 15:06

How do you test methods that fire asynchronous processes with JUnit?

I don\'t know how to make my test wait for the process to end (it is not exactly a unit test, it

18条回答
  •  一向
    一向 (楼主)
    2020-11-29 15:54

    If you want to test the logic just don´t test it asynchronously.

    For example to test this code which works on results of an asynchronous method.

    public class Example {
        private Dependency dependency;
    
        public Example(Dependency dependency) {
            this.dependency = dependency;            
        }
    
        public CompletableFuture someAsyncMethod(){
            return dependency.asyncMethod()
                    .handle((r,ex) -> {
                        if(ex != null) {
                            return "got exception";
                        } else {
                            return r.toString();
                        }
                    });
        }
    }
    
    public class Dependency {
        public CompletableFuture asyncMethod() {
            // do some async stuff       
        }
    }
    

    In the test mock the dependency with synchronous implementation. The unit test is completely synchronous and runs in 150ms.

    public class DependencyTest {
        private Example sut;
        private Dependency dependency;
    
        public void setup() {
            dependency = Mockito.mock(Dependency.class);;
            sut = new Example(dependency);
        }
    
        @Test public void success() throws InterruptedException, ExecutionException {
            when(dependency.asyncMethod()).thenReturn(CompletableFuture.completedFuture(5));
    
            // When
            CompletableFuture result = sut.someAsyncMethod();
    
            // Then
            assertThat(result.isCompletedExceptionally(), is(equalTo(false)));
            String value = result.get();
            assertThat(value, is(equalTo("5")));
        }
    
        @Test public void failed() throws InterruptedException, ExecutionException {
            // Given
            CompletableFuture c = new CompletableFuture();
            c.completeExceptionally(new RuntimeException("failed"));
            when(dependency.asyncMethod()).thenReturn(c);
    
            // When
            CompletableFuture result = sut.someAsyncMethod();
    
            // Then
            assertThat(result.isCompletedExceptionally(), is(equalTo(false)));
            String value = result.get();
            assertThat(value, is(equalTo("got exception")));
        }
    }
    

    You don´t test the async behaviour but you can test if the logic is correct.

提交回复
热议问题