2016-08-01 3 views
6

Я очень новичок в Котлине.Как проверить код, который вызывает функции верхнего уровня в Котлине?

У меня есть класс, который вызывает функцию верхнего уровня (что делает http-вызов). Я пытаюсь написать модульные тесты для своего класса, не выходя из сети.

Есть ли способ издеваться/заряжать/перехватывать вызов от моего класса до функции верхнего уровня Kotlin?

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 
     } 
    } 
} 

Он использует kittinunf/Fuel library для вызова HttpGet.

Он добавляет функцию верхнего уровня в String, которая в конечном итоге вызывает функцию объекта компаньона в Fuel (Fuel.get()).

В модульном тесте необходимо перехватить вызов httpGet, чтобы я мог вернуть строку json для теста.

+0

Эй, Бун .. У вас есть полный пример для этого? Я пытаюсь написать тесты Junit для моих топливных вызовов Kotlin. –

+0

Я следовал за предложением @ miensol и использовал Fuel.testMode() и переопределение executeRequest. – Boon

+0

это будет очень полезно, если вы можете опубликовать фрагмент кода или отправить ссылку github? –

ответ

6

Я призываю вас, чтобы инкапсулировать удаленных вызовов API позади интерфейса, который будет впрыскивается через конструктор к классу используя его:

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 
     } 
    } 
} 

Другой способ придать фальшивый Client для использования Fuel:

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

Большое спасибо за указатель! – Boon

+1

Как я могу сделать такую ​​же поддельную инъекцию клиента с помощью Java? Я думаю, что документация о топливе недостаточно ясна для этих случаев. – Yajairo87

4

Похоже, что «функции верхнего уровня» можно рассматривать как скрытые скрытые методы.

И с этой точки зрения лучший ответ: не используйте их таким образом. Это приводит к высокой, прямой связи; и делает ваш код более трудным для тестирования. Вы определенно хотите создать некоторый интерфейс Service, который должны использовать все ваши объекты; а затем используйте инъекцию зависимостей использования для оснащения вашего клиентского кода некоторым объектом, который реализует интерфейс Service.

Таким образом, вы также полностью избавляетесь от требования к Powermock.

Смежные вопросы