2016-02-19 8 views
27

Mockito tworzy instancję proxy, gdy coś jest szpiegowane. Czy istnieje jakiś sposób przekazywania zestawów ustawiających, które są następnie wykonywane w tej instancji proxy do rzeczywistej instancji, która znajduje się za nią?Jak poprawnie szpiegować działanie

Uzasadnienie: Mam instancję obiektu, której nie mam pod całkowitą kontrolą, tj. Działanie Androida. Mogę podać większość części mojej aplikacji jako wersję Proxy i działa dobrze tak, jak jest, , ale, ponieważ potrzebuję utworzyć szpiega/proxy bardzo wcześnie podczas fazy tworzenia działania, nie jest jeszcze w pełni utworzona, np. kontekst podstawowy nie jest dołączony. Dzieje się tak na instancji proxy i nie jest oczywiście używane przez samą instancję działania (która odnosi się do siebie poprzez Activity.this). Rezultatem jest to, że prowadzi to do wszelkiego rodzaju awarii, ponieważ rozdzielanie zasobów odbywa się poprzez ten kontekst bazowy, więc wewnętrzna maszyna Fragmentowa rzuca NPE i więcej.

Oto kod:

public class CustomAndroidJUnitRunner extends AndroidJUnitRunner { 
    @Override 
    public Activity newActivity(ClassLoader cl, String className, Intent intent) 
      throws InstantiationException, IllegalAccessException, ClassNotFoundException { 
     Activity activity = super.newActivity(cl, className, intent); 
     return maybeStubSomeDelegate(activity); 
    } 

    private Activity maybeStubSomeDelegate(Activity activity) { 
     if (!(activity instanceof SomeDelegate)) { 
      return activity; 
     } 
     Activity spiedActivity = spy(activity); 
     doReturn(SomeDelegateMock.getInstance()) 
      .when((SomeDelegate) spiedActivity) 
      .getDelegate(); 
     return spiedActivity; 
    } 
} 

Jestem pojęcia - jakieś pomysły?

+0

Dlaczego nie używacie espresso: https://google.github.io/android-testing-support-library/docs/espresso/ Więc można również kontrolować działalność. –

+0

Używam już Espresso, to nie ma nic wspólnego z moim pytaniem. –

+0

dodaje metodę @VisibleForTesting setDelegate() do aktywności poza pytaniem? Uważam, że każde podejście, które obejmuje wstrzykiwanie szpiegów z Działalności, zawsze będzie miało jakiś skrajny przypadek, w którym nie będzie działać. – jdonmoyer

Odpowiedz

0

Można użyć Robolectric stworzyć własny serwer proxy (lub jak nazywa je Robolectric „cień”) na swojej działalności,

Podczas tworzenia proxy można tworzyć własne ustawiające, które mogą wywołać metody obiektu rzeczywistego,

Jak stworzyć cień przykład:

@Implements(Bitmap.class) 
public class MyShadowBitmap { 

@RealObject private Bitmap realBitmap; 
private int bitmapQuality = -1; 

@Implementation 
public boolean compress(Bitmap.CompressFormat format, int quality, OutputStream stream) { 
    bitmapQuality = quality; 
    return realBitmap.compress(format, quality, stream); 
} 

public int getQuality() { 
    return bitmapQuality; 
} 
} 
} 

gdy @RealObject to prawdziwy przykład,

aby skorzystać z tej s Hadow użyciu Robolectric testy biegacz zdefiniować nową klasę testową następująco:

@RunWith(RobolectricTestRunner.class) 
@Config(shadows = MyShadowBitmap.class) 
public class MyTestClass {} 

Aby wyciągnąć bieżąca instancja cień użyć metody:

shadowOf() 

A w każdym razie, tu jest link, aby Robolectric:

http://robolectric.org/custom-shadows/

+0

Może to być przydatne do testów jednostkowych, ale tak naprawdę mówiłem o testowaniu oprzyrządowania :) –

+0

Przydaje się również do testowania oprzyrządowania (zakładając, że nie chcesz, aby działały na emulatorze urządzenia) –