14

Kotlin Erweiterungsfunktion ist großartig. Aber wie könnte ich einen Komponententest durchführen? Besonders die von Android SDK bereitgestellten Klassen (z. B. Context, Dialog).Komponententest auf Kotlin-Erweiterungsfunktion auf Android SDK-Klassen

Ich biete zwei Beispiele unten, und wenn jemand teilen könnte, wie ich sie Einheit prüfen könnte, oder wenn ich sie anders schreiben muss, wenn ich wirklich Unit-Test sie wollen.

fun Context.getColorById(colorId: Int): Int { 
    if (Build.VERSION.SDK_INT >= 23) 
     return ContextCompat.getColor(this, colorId) 
    else return resources.getColor(colorId) 
} 

und

fun Dialog.setupErrorDialog(body : String, onOkFunc:() -> Unit = {}): Dialog { 
    window.requestFeature(Window.FEATURE_NO_TITLE) 
    this.setContentView(R.layout.dialog_error_layout) 

    (findViewById(R.id.txt_body) as TextView).text = body 
    (findViewById(R.id.txt_header) as TextView).text = context.getString(R.string.dialog_title_error) 
    (findViewById(R.id.txt_okay)).setOnClickListener{ 
     onOkFunc() 
     dismiss() 
    } 
    return this 
} 

Jede Anregung helfen würde. Vielen Dank!

+1

Hallo, ich glaube nicht, dass Sie diese Funktionen im Unit-Test testen müssen. Erstens, bekommt Farbe von Android-Ressourcen und hängt nicht von Ihrem Anwendungscode ab. Der zweite zeigt errorDialog, warum benutzen Sie nicht Espresso oder Robotium oder ein anderes UI-Test-Framework, um zu überprüfen, ob es richtig angezeigt wird? – piotrek1543

+0

Danke piotrek. Der Code ist nur zum Beispiel. Der Hauptteil der Frage besteht darin, zu untersuchen, wie Unit-Tests mit der Extension-Funktion durchgeführt werden können, falls eine gewisse Logik dafür benötigt wird. Ist das etwas unerreichbar oder fehlt mir etwas? Vielen Dank. – Elye

+0

Ich suche es auch. Hast du es @Elye gefunden? – elsennov

Antwort

2

Die Art und Weise, in der ich derzeit Erweiterungsfunktionen in Android-Klassen teste, besteht darin, die Android-Klasse zu verspotten. Ich weiß, dies ist keine optimale Lösung, da es die getestete Klasse verspottet und gewisse Kenntnisse darüber benötigt, wie die Funktion funktioniert (wie es immer beim Mocking der Fall ist), aber da Erweiterungsfunktionen intern als statische Funktionen implementiert sind, denke ich, dass es akzeptabel ist bis jemand mit etwas besser kommt.

Als Beispiel betrachten Sie die JsonArray Klasse. Wir haben eine Erweiterungsfunktion definiert das letzte Element des Index für die Aufnahme:

fun JSONArray.lastIndex() = length() - 1 

Der nach Test (mit dem Spek Test-Framework und mockito-kotlin) sieht wie folgt aus.

@RunWith(JUnitPlatform::class) 
object JsonExtensionTestSpec : Spek({ 

    given("a JSON array with three entries") { 
     val jsonArray = mock<JSONArray> { 
      on { length() } doReturn 3 
     } 

     on("getting the index of the last item") { 
      val lastIndex = jsonArray.lastIndex() 

      it("should be 2") { 
       lastIndex shouldBe 2 
      } 
     } 
    } 

    given("a JSON array with no entries") { 
     val jsonArray = mock<JSONArray>({ 
      on { length() } doReturn 0 
     }) 

     on("getting the index of the last item") { 
      val lastIndex = jsonArray.lastIndex() 

      it("should be -1") { 
       lastIndex shouldBe -1 
      } 
     } 
    } 
}) 

Die Schwierigkeit mit Ihren Funktionen ist, dass sie intern auch Android-Klassen verwenden. Leider habe ich momentan keine Lösung dafür.