如何测试在Kotlin中调用顶级函数的代码?

Boo*_*oon 9 unit-testing mockito powermock kotlin

我对Kotlin很新.

我有一个类调用顶级函数(进行http调用).我正在尝试为我的班级编写单元测试而不用它去网络.

有没有办法模拟/ powermock /拦截从我的班级到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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它使用kittinunf/Fuel库进行httpGet调用.

它为String添加了一个顶级函数,最终调用Fuel(Fuel.get())中的伴随对象函数.

单元测试需要拦截对httpGet的调用,以便我可以为测试返回一个json字符串.

mie*_*sol 8

我鼓励您将远程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 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种方式是注入假的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
}
Run Code Online (Sandbox Code Playgroud)


Gho*_*ica 5

似乎“顶级函数”可以被视为变相的静态方法。

从这个角度来看,更好的答案是:不要以这种方式使用它们。这会导致高度直接的耦合;并使您的代码更难测试。你肯定想创建一些你的所有对象都应该使用的接口服务;然后使用依赖注入为您的客户端代码配备一些实现Service接口的对象。

通过这样做,您还可以完全摆脱对 Powermock 的要求。