如何测试在 Kotlin 中调用顶级函数的代码?
How to test code that calls top level functions in Kotlin?
我对 Kotlin 很陌生。
我有一个 class 调用顶级函数(进行 http 调用)。我正在尝试为我的 class 编写单元测试,而无需它进入网络。
有没有办法 mock/powermock/intercept 从我的 class 调用 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 的调用,以便我可以 return 一个 json 字符串用于测试。
我鼓励您将远程 API 调用封装在一个接口后面,该接口将通过构造函数注入到 class 使用它:
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
}
看来"top level functions"可以看做变相的静态方法
从这个角度来看,更好的答案是:不要以这种方式使用它们。这会导致高度直接的耦合;并使您的代码更难测试。您肯定想创建一些接口 Service,您的所有对象都应该使用该接口;然后使用依赖注入为您的客户端代码配备一些实现 Service 接口的对象。
这样做,您也完全摆脱了对 Powermock 的要求。
我对 Kotlin 很陌生。
我有一个 class 调用顶级函数(进行 http 调用)。我正在尝试为我的 class 编写单元测试,而无需它进入网络。
有没有办法 mock/powermock/intercept 从我的 class 调用 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 的调用,以便我可以 return 一个 json 字符串用于测试。
我鼓励您将远程 API 调用封装在一个接口后面,该接口将通过构造函数注入到 class 使用它:
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
}
看来"top level functions"可以看做变相的静态方法
从这个角度来看,更好的答案是:不要以这种方式使用它们。这会导致高度直接的耦合;并使您的代码更难测试。您肯定想创建一些接口 Service,您的所有对象都应该使用该接口;然后使用依赖注入为您的客户端代码配备一些实现 Service 接口的对象。
这样做,您也完全摆脱了对 Powermock 的要求。