2013-08-06 61 views
3

我需要用JUnit測試這個方法的Mockito的Mockito:模擬異步方法

function uploadData() { 
    myObject.getThreadPool().execute(new Runnable() { 
       @Override 
       public void run() { 
        upload(arguments, callbackContext); 
       } 
      }); 
     } 

如何嘲笑myObject的調用上傳(參數,callbackContext)不是在後臺線程?

+0

如果您要模擬'myObject'來在當前線程中調用'upload',而不是像您所問的那樣調用'upload';那麼你根本就不會測試這種方法 - 你會嘲笑你已經着手測試的東西。 –

回答

0

我認爲有以下將工作:

Mockito.doAnswer(new Answer() { 
    @Override 
    public Object answer(InvocationOnMock invocation) throws Throwable { 
     upload(arguments, callbackContext); 
    }).when(myObjectSpy.getThreadPool()).execute(Mockito.any(Runnable.class)); 

,但我真的不肯定。

2

你需要在這裏做一些事情。首先,用一個模擬代替ThreadPool,所以你完全可以使用模擬execute。然後使用ArgumentCaptor中的a verify call訪問Runnable。最後,觸發Runnable,然後測試狀態。

@Test public void shouldUploadInBackground() { 
    // declare local variables 
    MyObject mockMyObject = Mockito.mock(MyObject.class); 
    ThreadPool mockThreadPool = Mockito.mock(ThreadPool.class); 
    ArgumentCaptor<Runnable> runnableCaptor = 
     ArgumentCaptor.forClass(Runnable.class); 

    // create the system under test 
    when(mockMyObject.getThreadPool()).thenReturn(mockThreadPool); 
    SystemUnderTest yourSystemUnderTest = createSystem(mockThreadPool); 

    // run the method under test 
    yourSystemUnderTest.uploadData(); 

    // set the runnableCaptor to hold your callback 
    verify(mockThreadPool).execute(runnableCaptor.capture()); 

    // here you can test state BEFORE the callback executes 
    assertFalse(yourSystemUnderTest.isDataUploaded()); 

    // call run on the callback 
    runnableCaptor.getValue().run(); 

    // here you can test state AFTER the callback executes 
    assertTrue(yourSystemUnderTest.isDataUploaded()); 
}