2014-12-23 5 views
5

Ich versuche Espresso (2.0) zu verwenden, um zu überprüfen, ob der Text in einem Listenadapterelement an einer bestimmten Position richtig ist und für die Lebensdauer meines Ich kann die richtigen Methoden nicht finden, um anzurufen.So verwenden Sie Espresso, um Artikel im Adapter an einer bestimmten Position zu testen

Mein Adaptertyp (IconRowAdapter) enthält eine Liste von IconRow Objekten. Jede IconRow hat eine getText() Methode, die den Text dieses Elements zurückgibt.

Hier ist der Nicht-Espresso-Arbeitstestcode, der verifiziert, dass das IconRow-Objekt an Position 0 im Adapter den erwarteten Text ("Artists") hat.

public void testHomeActivityMenu() { 
    ListView list = (ListView) getActivity().findViewById(R.id.item_list); 
    IconRowAdapter adapter = (IconRowAdapter) list.getAdapter(); 

    assertEquals(adapter.getItem(0).getText(), "Artists"); 
} 

Dies funktioniert.

Ich habe auf den folgenden Espresso Code sortierten Variationen versucht, das Gleiche zu tun,

onData(is(instanceOf(IconRowAdapter.class))) 
     .atPosition(0) 
     .check(matches(withItemContent("Artists"))); 

wo withItemContent() wie folgt aussieht:

public static Matcher<Object> withItemContent(String expectedText) { 
    checkNotNull(expectedText); 
    return withItemContent(equalTo(expectedText)); 
} 

@SuppressWarnings("rawtypes") 
public static Matcher<Object> withItemContent(final Matcher<String> itemTextMatcher) { 
    checkNotNull(itemTextMatcher); 
    return new BoundedMatcher<Object, IconRow>(IconRow.class) { 
     @Override 
     public boolean matchesSafely(IconRow iconRow) { 
      return itemTextMatcher.matches(iconRow.getText()); 
     } 

     @Override 
     public void describeTo(Description description) { 
      description.appendText("with item content: "); 
      itemTextMatcher.describeTo(description); 
     } 
    }; 
} 

Was würde ich erwarten, dass zu tun ist:

  • Holen Sie sich die Daten vom Adapter, der eine Instanz von IconRowAdapter ist (von denen ' s nur eins in der Aktivität) ...
  • ... den Eintrag an Position 0 im Adapter finden ...
  • ... mit withItemContent() überprüfen, ob der Text im Element an dieser Position übereinstimmt „Künstler“

Wenn ich laufen, dass ich die folgende Fehlermeldung erhalten:

Caused by: java.lang.RuntimeException: No data found matching: is an instance of 
uk.org.ngo.squeezer.IconRowAdapter contained values: <[Data: 
[email protected] (class: 
uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 0, Data: 
[email protected] (class: 
uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 1, Data: 
[email protected] (class: 
uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 2, Data: 
[email protected] (class: 
uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 3, Data: 
[email protected] (class: 
uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 4, Data: 
[email protected] (class: 
uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 5, Data: 
[email protected] (class: 
uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 6, Data: 
[email protected] (class: 
uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 7, Data: 
[email protected] (class: 
uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 8, Data: 
[email protected] (class: 
uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 9, Data: 
[email protected] (class: 
uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 10, Data: 
[email protected] (class: 
uk.org.ngo.squeezer.IconRowAdapter$IconRow) token: 11]> 

es gibt 12 Artikel in IconRowAdapter, so habe ich etwas Vertrauen, dass sie in der richtigen Adapter sucht.

Der gesamte Beispielcode und die Dokumentation, die ich finden konnte, geht davon aus, dass Sie versuchen, einen Eintrag im Adapter zu finden, um darauf zu klicken (und dass der Wert in einer anderen Ansicht resultiert Ändern). Ich kann nichts finden, das darüber redet, wie man den Wert eines bestimmten Artikels in einem Adapter überprüft.

Alle Einsichten dankbar erhalten.

bearbeiten hinzuzufügen:

Was Arbeit tut, ist der folgende:

onData(anything()) 
     .inAdapterView(withId(R.id.item_list)) 
     .atPosition(0) 
     .check(matches(hasDescendant(
       allOf(withId(R.id.text1), withText(containsString("Artists")))))); 

Wenn ich verstehe, dass das testet den Wert der R.id.text1 Ansicht richtig, eher als der Wert in der Adapter. Ich denke, das ist sinnvoll für einen UI-Test, aber ich bin immer noch daran interessiert, herauszufinden, wie (wenn?) Ich Espresso verwenden kann, um den Inhalt eines Elements im Adapter zu testen.

Antwort

3

Der Matcher, der als Argument an onData() übergeben wurde, muss mit dem von Adapter.getItem() zurückgegebenen Wert übereinstimmen. So stimmt die erste Version nicht überein, weil der falsche Typ verwendet wird.Es sollte sein:

Was auch eine Falle sein kann, ist equalTo auf verschiedenen Arten von CharSequences. String ist eine CharSequence, aber wenn IconRow.getText() CharSequence anstelle von String zurückgibt, dann kann dies auch Spannable, Editable usw. sein, in welchem ​​Fall equalTo nicht übereinstimmen würde. Wenn also IconRow.getText() irgendetwas außer String zurückgibt, vergewissern Sie sich, dass Sie es vor dem Vergleich in einen String konvertieren.

0

Probieren Sie dies aus es funktionieren muss:

//check that item is present in list at position 0 
onData(withItemContent("Artists")) 
    .inAdapterView(withId(R.id.list_view)) 
    .atPosition(0) 
    .check(matches(isDisplayed())); 

Wenn Sie atPosition(0) löschen, dann werden Sie nur Präsenz in den Adapter Ansicht überprüfen.

+0

Methode 'withItemContent' funktioniert nicht richtig in Kotlin. Vielleicht hast du eine Ahnung davon? – Morozov

+0

Haben Sie den Matcher modifiziert? – denys

+0

ja. etwas wie das 'fun withItemContent (expectedText: String): Matcher { checkNotNull (expectedText) Rückgabe withItemContent (equalTo (expectedText) .toString()) }' – Morozov