Reputation: 495
In my Spring boot application, I have below two methods, I am writing JUnit for method1 and mocking method processQuery(). but I don't know why when the control reaches to result.get() , It got stuck, and not moving further.
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 helps me with the above issue.
Upvotes: 0
Views: 3937
Reputation: 20598
You are mocking risk.processQuery()
with an uncompleted CompletableFuture
CompletableFuture<ExecutionResult> result = new CompletableFuture<ExecutionResult>();
Mockito.doReturn(result).when(risk).processQuery(Mockitt.anyString(),Mockito.any());
When you call get()
on a CompletableFuture
, it waits until it is completed with a value or an exception. Here you future is never completed, so it waits indefinitely.
You have three solutions here:
define your mock such that it returns an already completed future:
CompletableFuture<ExecutionResult> result = CompletableFuture.completedFuture(someResult);
make the test call entry.method1()
in a separate thread (e.g. with CompletableFuture.supplyAsync()
) and then complete the result with result.complete(someResult)
in the test;
refactor your code such that method1()
becomes asynchronous as well, something like:
public CompletableFuture<String> method1(){
--some process and then calling method 2
CompletableFuture<ExecutionResult> result =
risk.processQuery(graphQLRequest, context);
return result.thenApply(result -> result.toString());
}
then adapt your test to mimic an asynchronous response:
@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());
}
Upvotes: 2