2017-06-07 29 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的例子吗? –

相关问题