2016-08-01 21 views
6

Ich bin sehr neu in Kotlin.Wie Code zu testen, der Top-Level-Funktionen in Kotlin aufruft?

Ich habe eine Klasse, die eine Top-Level-Funktion aufruft (die einen http-Aufruf macht). Ich versuche Komponententests für meine Klasse zu schreiben, ohne dass es ins Netzwerk geht.

Gibt es eine Möglichkeit, den Anruf von meiner Klasse auf die Top Level-Funktion von Kotlin abzuspielen/powermock/abzufangen?

class MyClass { 
    fun someMethod() { 
     // do some stuff 
     "http://somedomain.com/some-rest/action".httpGet(asList("someKey" to "someValue")).responseString { (request, response, result) -> 
      // some processing code 
     } 
    } 
} 

Es wird mit dem kittinunf/Fuel library für den HttpGet Anruf.

Es fügt String eine Top-Level-Funktion hinzu, die letztendlich eine Companion-Objektfunktion in Fuel (Fuel.get()) aufruft.

Der Komponententest muss den Aufruf von httpGet abfangen, damit ich eine JSON-Zeichenfolge für den Test zurückgeben kann.

+0

Hey Boon .. Haben Sie ein komplettes Beispiel dafür? Ich versuche, Junit-Tests für meine Kotlin Kraftstoffanrufe schreiben –

+0

Ich folgte @ MIENSOL Vorschlag und verwendet Fuel.testMode() und die executeRequest override. – Boon

+0

es wird eine große Hilfe sein, wenn Sie das Code-Snippet posten oder einen GitHub-Link senden können? –

Antwort

6

Ich ermutige Sie, Remote-API-Aufrufe hinter einer Schnittstelle zu kapseln, die durch Konstruktor der Klasse injiziert werden wäre es mit:

class ResponseDto 
interface SomeRest { 
    fun action(data:Map<String,Any?>): ((ResponseDto)->Unit)->Unit 
} 
class FuelTests(val someRest: SomeRest) { 
    fun callHttp(){ 
     someRest.action(mapOf("question" to "answer")).invoke { it:ResponseDto -> 
      // do something with response 
     } 
    } 
} 

Eine weitere Möglichkeit, eine gefälschte Client zu injizieren ist durch Fuel verwendet werden:

FuelManager.instance.client = object: Client { 
    override fun executeRequest(request: Request): Response { 
     return Response().apply { 
      url = request.url 
      httpStatusCode = 201 
     } 
    } 
} 

Fuel.testMode() 

"http://somedomain.com/some-rest/action".httpGet(listOf()).responseString { request, response, result -> 
    print(response.httpStatusCode) // prints 201 
} 
+0

Vielen Dank für den Zeiger! – Boon

+1

Wie könnte ich die gleiche gefälschte Client-Injektion mit Java machen? Ich denke, die Fuel-Dokumentation ist für diese Fälle nicht klar genug. – Yajairo87

4

Es scheint, dass "Top-Level-Funktionen" als statische Methoden in Verkleidung gesehen werden können.

Und von diesem Standpunkt aus ist die bessere Antwort: Verwenden Sie sie nicht auf diese Weise. Dies führt zu einer hohen direkten Kopplung; und macht Ihren Code schwieriger zu testen. Sie möchten definitiv eine Schnittstelle Service erstellen, die alle Ihre Objekte verwenden sollten; Verwenden Sie dann die Abhängigkeitsinjektion, um den Clientcode mit einem Objekt auszustatten, das die Service-Schnittstelle implementiert.

Dadurch werden Sie auch die Anforderung an Powermock vollständig los.