junit: метод get CompletableFuture <ExecutionResult>никогда не возвращается - PullRequest
0 голосов
/ 14 марта 2019

В моем загрузочном приложении Spring ниже приведены два метода: я пишу JUnit для method1 и метод mocking processQuery () .но я не знаю, почему, когда элемент управления достигает result.get () , он застрял и не двигается дальше.

Method 1:
public class Entry(){
public string method1(){
   --some process and then calling method 2
 CompletableFuture<ExecutionResult> result = 
 risk.processQuery(graphQLRequest, context);
 **result.get();** **--Control got stuck here** 
 system.out.println("control not reaching here ");
 }
}

  **TestClass ::**

public class testMain(){
  @InjectMock
  Entry entry;
  @Mock
  Risk risk;

 @Before
    public void setup() {
    entry= new Entry();
    MockitoAnnotations.initMocks(this);
   }

 @Test
   public void testMethod1(){
     CompletableFuture<ExecutionResult> result = new 
     CompletableFuture<ExecutionResult>();


Mockito.doReturn(result).when(risk).processQuery(Mockitt.anyString(),Mockito.any());

entry.method1();
}

Kinde помогает мне с вышеуказанной проблемой.

1 Ответ

1 голос
/ 14 марта 2019

Вы издеваетесь risk.processQuery() с незавершенным CompletableFuture

CompletableFuture<ExecutionResult> result = new CompletableFuture<ExecutionResult>();
Mockito.doReturn(result).when(risk).processQuery(Mockitt.anyString(),Mockito.any());

Когда вы вызываете get() на CompletableFuture, он ждет, пока не завершится со значением или исключением.Здесь ваше будущее никогда не завершается, поэтому оно ждет бесконечно.

У вас есть три решения:

  • определите свой макет так, чтобы он возвращал уже завершенное будущее:

    CompletableFuture<ExecutionResult> result = CompletableFuture.completedFuture(someResult);
    
  • сделать тестовый вызов entry.method1() в отдельном потоке (например, с CompletableFuture.supplyAsync()), а затем завершить результат с result.complete(someResult) в тесте;

  • рефакторинг вашего кода таким образом, что method1() также становится асинхронным, что-то вроде:

    public CompletableFuture<String> method1(){
        --some process and then calling method 2
        CompletableFuture<ExecutionResult> result = 
        risk.processQuery(graphQLRequest, context);
        return result.thenApply(result -> result.toString());
    }
    

    , затем адаптирует ваш тест для имитации асинхронного ответа:

    @Test
    public void testMethod1(){
        CompletableFuture<ExecutionResult> result = new CompletableFuture<ExecutionResult>();
        Mockito.doReturn(result).when(risk).processQuery(Mockitt.anyString(),Mockito.any());
    
        CompletableFuture<String> method1Result = entry.method1();
        result.complete(someResult);
        assertEquals("some String", method1Result.join());
    }
    
...