2017-06-07 46 views
0

我正在編寫一個需要偵聽UDP廣播消息的Android應用程序。爲什麼我得到錯誤'android.os.AsyncTask中的方法執行未被模擬'

我試圖嘲笑一個監聽器類中的AsyncTask,所以我可以單元測試它。

問題是我總是得到錯誤 java.lang.RuntimeException:方法在android.os.AsyncTask中執行沒有被模擬。

public class DiscoveryListener 
{ 
    WorkGroupEventHandler workGroupEventHandler; 

    private AsyncTask<Void, Void, Void> asyncTask; 
    private boolean listener_active = false; 

    public boolean GetListener_active() 
    { 
     return listener_active; 
    } 

    public DiscoveryListener(WorkGroupEventHandler eventHandler) 
    { 
     workGroupEventHandler = eventHandler; 
    } 

    public void Start() 
    { 
     if (listener_active == false) 
     { 
      listener_active = true; 
      RunUdpListener(); 
     } 
    } 

    public void Stop() 
    { 
     listener_active = false; 
     asyncTask.cancel(true); 
    } 

    public void RunUdpListener() 
    { 
     asyncTask = new AsyncTask<Void, Void, Void>() 
     { 

     @Override 
     protected Void doInBackground(Void... params) 
     { 
      byte[] msg = new byte[4096]; 
      DatagramPacket datagramPacket = new DatagramPacket(msg, msg.length); 
      MulticastSocket multicastReceiveSocket = null; 

      try 
      { 
       multicastReceiveSocket = new MulticastSocket(60000); 

       while (listener_active) 
       { 
        if (isCancelled() == false) 
        { 
         multicastReceiveSocket.receive(datagramPacket); 
         ProcessIncommingMessage(datagramPacket.getAddress(), msg); 
        } 
       } 
      } 
      catch (Exception e) 
      { 
       e.printStackTrace(); 
      } 
      finally 
      { 
       if (multicastReceiveSocket != null) 
       { 
        multicastReceiveSocket.close(); 
       } 
      } 

      return null; 
      } 
     }; 

     asyncTask.execute(); 
    } 
} 


@RunWith(PowerMockRunner.class) 
@PrepareForTest({android.util.Log.class, android.os.AsyncTask.class}) 
public class DiscoveryListenerUnitTest 
{ 
    private WorkGroupEventHandler eventHandler = new WorkGroupEventHandler() 
    { 
     @Override 
     public void onWorkGroupEventHandle(String IpAddress, String Workgroup, String SerialNumber) 
     { 
     } 
    }; 

    private DiscoveryListener discoveryListener = new DiscoveryListener(eventHandler); 
    private AsyncTask asyncTask; 

    @Test 
    public void discoveryListener_doesStart() throws Exception 
    { 
     PowerMockito.mockStatic(android.util.Log.class); 

     PowerMockito.whenNew(AsyncTask.class).withNoArguments().thenReturn(asyncTask); 
     asyncTask = PowerMockito.mock(AsyncTask.class); 
     when(asyncTask.execute()).thenReturn(null); 

     discoveryListener.Start(); 
     assertEquals(true, discoveryListener.GetListener_active()); 
    } 
} 

回答

0

AsyncTask.execute是final的,Mockito不能模擬最終的類或方法。

Cannot mock final methods - their real behavior is executed without any exception. Mockito cannot warn you about mocking final methods so be vigilant. 

具體地說,這是因爲Java可以解決在編譯時鏈接的,這意味着可以的Mockito不能使用其產生的子類和方法重寫來改變行爲。

你可以選擇使用Powermock,它使用一個特殊的類加載器來重寫舊的行爲,或者Robolectric,它可以做同樣的事情,但用Android專用的測試友好替代實現(「陰影」)替換類,包括AsyncTask 。

+0

感謝您的回覆。我以爲我使用PowerMock通過調用asyncTask = PowerMockito.mock(AsyncTask.class);你能舉一個我如何使用PowerMock的例子嗎? –

相關問題