title: Unit testing method that uses callback and SynchronousQueue to track results
body: <p>I'm using Mockito to test a method that internally makes a networking call and returns a value based on the result of the networking call. This method uses a SynchronousQueue to wait for the result, and the result is set by the callback for the networking call:</p>
  
  <pre><code>HelperClass helperClassObject = new HelperClassObject();
  
  ...
  
  public SomeResultCode methodWithNetworkCall() {
      SynchronousQueue&lt;SomeResultCode&gt; resultQueue = new SynchronousQueue&lt;&gt;();
  
      // some condition checking code
  
      helperClassObject.makeNetworkCall(new GenericCallback() {
          @Override
          public void onSuccess(JSONObject response) {
              resultQueue.offer(SomeResultCode.SUCCESS);
          }
  
          @Override
          public void onFailure(VolleyError error) {
              resultQueue.offer(SomeResultCode.FAILURE);
          }
      });
  
      SomeResultCode resultCode = null;
      try {
          resultCode = resultQueue.poll(1, TimeUnit.MINUTES);
      } catch (InterruptedException e) {
  
      }
      return resultCode == null ? SomeResultCode.FAILURE : resultCode;
  }
  </code></pre>
  
  <p>In one of my unit test methods I'm trying to verify that SUCCESS is returned upon successful network call. I've tried using ArgumentCaptor and doAnswer to trigger the callback's onSuccess. However, the method is returning FAILURE. I put a breakpoint in the onSuccess, and it looks like when I use the ArgumentCaptor way the onSuccess is triggered AFTER the poll has timed out. When I use the doAnswer way, I see onSuccess called during the setup (doAnswer.when) but not after I actually call the method. What am I doing wrong?</p>
  
  <p><strong>EDIT</strong>
  Stepping through the code again, it looks like answer is called from within the method I'm testing (i.e. when I call testObject.methodWithNetworkCall during my test), NOT during setup. So it is doing exactly what it is supposed to do: responding with onSuccess. But it is responding with onSuccess BEFORE poll is called. So it seems the problem is not that answer and mocking in general is not working/set up wrong, it is an issue with testing with SynchronousQueue.</p>
  
  <p>Here is my test code:</p>
  
  <pre><code>public class TestClassUnitTest {
      TestClass sut;
      HelperClass helperClassObject = mock(HelperClass.class);
  
      @Before
      public void setup() {
          sut = new TestClass();
          injectField(sut, "helperClassFieldName", helperClassObject);
      }
  
      public void injectField(Object testObject, String fieldName, T mockToInject) {
          // some code using reflection to inject the mock object into the test object
      }
  
      @Test
      public void testMethodWithNetworkCallWithCaptor() {
          ArgumentCaptor&lt;GenericCallback&gt; captor = ArgumentCaptor.forClass(GenericCallback.class);
          SomeResultCode result = sut.methodWithNetworkcall();
          verify(helperClassObject, times(1)).makeNetworkCall(captor.capture());
          captor.getValue().onSuccess(new JSONObject());
          Assert.assertEquals(SomeResultCode.SUCCESS, result);
      }
  
      @Test
      public void testMethodWithNetworkCallWithDoAnswer() {
          doAnswer(new Answer(){
              @Override
              public Object answer(InvocationOnMock invocation) throws Throwable {
                  ((GenericCallback)invocation.getArguments()[0]).onSuccess(new JSONObject());
                  return null;
              }
          }).when(helperClassObject).makeNetworkCall(any(GenericCallback.class));
          SomeResultCode result = sut.methodWithNetworkcall();
          Assert.assertEquals(SomeResultCode.SUCCESS, result);
       }
  }
  </code></pre>