2017-04-24 1 views
1

Ich versuche mein Netzwerkmodul zu testen. Wenn ich dies auf einem Simulator oder einem Gerät ausführe, ist der Handler in Ordnung, aber wenn ich versuche, es aus Tests heraus zu tun, wird handler = null und der Callback wird nicht aufgerufen. Wie kann ich dieses Problem lösen?Android Handler ist null beim Testen mit Junit

public void performCall(Call callToPerform){ 
    callToPerform.call.enqueue(new okhttp3.Callback() { 
     Handler handler = new Handler(); 

     @Override 
     public void onFailure(okhttp3.Call call, IOException e) { 
      handler.post(() -> { 
       for (Callback callback : callToPerform.callbacks) { 
        callback.onFailure(callToPerform, e); 
       } 
      }); 
     } 

     @Override 
     public void onResponse(okhttp3.Call call, final okhttp3.Response response){ 
      handler.post(() -> { 
       for (Callback callback : callToPerform.callbacks) { 
        try { 
         callback.onResponse(callToPerform, new Response(response.body().bytes(), response.headers().toMultimap())); 
        } catch (IOException e) { 
         callback.onFailure(call, e); 
        } 
       } 
      }); 
     } 
    }); 
} 

Meine Graddle App-Datei enthält diese Parameter.

testOptions { 
    unitTests.returnDefaultValues = true 
} 

Antwort

0

Ok, nach ein paar Stunden der Forschung, die ich Lösung gefunden habe, und es ist ähnlich wie this:

package com.dpmedeiros.androidtestsupportlibrary; 

import android.os.Handler; 
import android.os.Looper; 

import org.mockito.invocation.InvocationOnMock; 
import org.mockito.stubbing.Answer; 
import org.powermock.api.mockito.PowerMockito; 

import java.util.concurrent.Executors; 
import java.util.concurrent.ScheduledExecutorService; 
import java.util.concurrent.TimeUnit; 

import static org.mockito.Mockito.*; 

/** 
* Utility methods that unit tests can use to do common android library mocking that might be needed. 
*/ 
public class AndroidMockUtil { 

    private AndroidMockUtil() {} 
    /** 
    * Mocks main thread handler post() and postDelayed() for use in Android unit tests 
    * 
    * To use this: 
    * <ol> 
    *  <li>Call this method in an {@literal @}Before method of your test.</li> 
    *  <li>Place Looper.class in the {@literal @}PrepareForTest annotation before your test class.</li> 
    *  <li>any class under test that needs to call {@code new Handler(Looper.getMainLooper())} should be placed 
    *  in the {@literal @}PrepareForTest annotation as well.</li> 
    * </ol> 
    * 
    * @throws Exception 
    */ 
    public static void mockMainThreadHandler() throws Exception { 
     PowerMockito.mockStatic(Looper.class); 
     Looper mockMainThreadLooper = mock(Looper.class); 
     when(Looper.getMainLooper()).thenReturn(mockMainThreadLooper); 
     Handler mockMainThreadHandler = mock(Handler.class); 
     Answer<Boolean> handlerPostAnswer = new Answer<Boolean>() { 
      @Override 
      public Boolean answer(InvocationOnMock invocation) throws Throwable { 
       Runnable runnable = invocation.getArgumentAt(0, Runnable.class); 
       Long delay = 0L; 
       if (invocation.getArguments().length > 1) { 
        delay = invocation.getArgumentAt(1, Long.class); 
       } 
       if (runnable != null) { 
        mainThread.schedule(runnable, delay, TimeUnit.MILLISECONDS); 
       } 
       return true; 
      } 
     }; 
     doAnswer(handlerPostAnswer).when(mockMainThreadHandler).post(any(Runnable.class)); 
     doAnswer(handlerPostAnswer).when(mockMainThreadHandler).postDelayed(any(Runnable.class), anyLong()); 
     PowerMockito.whenNew(Handler.class).withArguments(mockMainThreadLooper).thenReturn(mockMainThreadHandler); 
    } 

    private final static ScheduledExecutorService mainThread = Executors.newSingleThreadScheduledExecutor(); 

} 
1

Wenn Sie diesen Beispielcode auf JUnit ausführen, wird dies nicht funktionieren, weil JUnit-Tests auf einer JVM ausgeführt werden, und instrumentierte Tests auf einem Simulator ausgeführt werden oder Real Geräte

Sie können einen Blick auf Link, es erklärt, warum:

Instrumented tests or Local tests

+0

Toller Artikel, danke! – quaddef

Verwandte Themen