2016-09-29 22 views
5

Próbuję wykonać prosty test espresso, który znajdzie pierwszy element w postaci RecyclerView bez konkretnej etykiety i kliknij na niego. Do tego dodałam espresso-contrib osiągnąć do projektu tak:Brak wirtualnej metody findViewHolderForPosition (I) podczas próby kliknięcia elementu RecyclerView przy użyciu Espresso

androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.2') { 
    // Necessary to avoid version conflicts 
    exclude group: 'com.android.support', module: 'appcompat' 
    exclude group: 'com.android.support', module: 'design' 
    exclude group: 'com.android.support', module: 'support-v4' 
    exclude group: 'com.android.support', module: 'appcompat-v7' 
    exclude group: 'com.android.support', module: 'support-annotations' 
    exclude module: 'recyclerview-v7' 
} 

i napisał następujące wyrażenie w moim przypadku testu: onView(withId(R.id.sresults_list_recycler)).perform(RecyclerViewActions.actionOnHolderItem(new FirstNotSoldOutMatcher(), click()).atPosition(1));

Matcher działa idealnie i RecyclerView został przewinięty do elementu docelowego. Ale dostaję błąd:

java.lang.NoSuchMethodError: No virtual method findViewHolderForPosition(I)Landroid/support/v7/widget/RecyclerView$ViewHolder; in class Landroid/support/v7/widget/RecyclerView; or its super classes (declaration of 'android.support.v7.widget.RecyclerView' appears in /data/app/com.example-1/base.apk) 
at android.support.test.espresso.contrib.RecyclerViewActions$ActionOnItemAtPositionViewAction.perform(RecyclerViewActions.java:288) 
at android.support.test.espresso.contrib.RecyclerViewActions$ActionOnItemViewAction.perform(RecyclerViewActions.java:232) 
at android.support.test.espresso.ViewInteraction$1.run(ViewInteraction.java:144) 
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at android.os.Handler.handleCallback(Handler.java:751) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6077) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 

Wygląda to dziwnie. Czytałem w dokumentacji Google, że metoda findViewHolderForPosition jest obecnie przestarzała, ale nadal powinna tam być. Mam również włączoną obsługę wielu języków w aplikacji, ale zgodnie z dokumentami jest ona obsługiwana po wyjęciu z pudełka, więc nie powinno to stanowić problemu.

Czy masz pojęcie, co może być nie tak z tym testem?

Odpowiedz

8

OK, w moim przypadku problem był w ProGuard zmniejszanie nieużywanych metod. Wyłączenie go dla testów pomogło.

Dla przyszłych poszukiwaczy - jeśli nie chcesz, aby wyłączyć ProGuard do debugowania dodanie tej linii do PROGUARD config powinien pomóc też:

-keepclasseswithmembers public class android.support.v7.widget.RecyclerView { *; } 

Należy również pamiętać, że zasada ta powinna zostać dodana do regularnej PROGUARD plik (ten z listy w proguardFiles), a nie testowy (zadeklarowany jako testProguardFile)

+0

Miałem ten sam problem. To rozwiązanie działa. Dzięki człowiekowi! –

+0

@Bersh dlaczego w 'proguardFiles', a nie w' testProguardFiles'? powinny to być tylko testy ... – Caipivara

+0

@Caipivara, ponieważ pamiętam, że "testProguardFiles" miały zastosowanie tylko do kodu testowego (w pakiecie testowym), podczas gdy musimy zachować metody w samej aplikacji. – Bersh