我有一个函数可以对外部API进行API调用
让我们说一下该函数执行的操作很简单,如下所示。仅供参考,需要导入scala.io.Source
def myFunction(apiRequestUrl: String) : MyObject = {
val response: String = Source.fromURL(apiRequestUrl).mkString
val formatedResponse: MyObject = formatResponseFunction(response)
formatedResponse
}
我知道我可能收到的一些错误代码是400、404等...,我只想以此处理所有错误代码。怎么办呢?我发现的示例似乎正在测试一个人自己构建的REST API,而不是对其他人的外部API的函数调用
答案 0 :(得分:1)
对于模拟外部服务调用,您可以使用Mockito,这是一个模拟框架。 Mockito非常易于使用,您可以为外部呼叫提供存根。例如
val m = mock[io.Source.type]
在这里模拟源代码,然后在调用fromUrl
函数时提供所需的行为。
即
when(m.fromUrl("external service url")) thenReturn("result")
答案 1 :(得分:1)
首先,您必须注入要用模拟替换的依赖项,不能对函数内的静态调用进行模拟/存根
在方案中,您还有另一个问题:依赖项Source
是一个对象,不能模拟对象,只能模拟非最终类和特征。此外,模拟第3方API被认为是错误的做法...
解决所有这些问题的好方法是重新编写类似的代码
trait HttpAdapter {
def fromUrl(apiRequestUrl: String): String = Source.fromURL(apiRequestUrl).mkString
}
object HttpAdapter extends HttpAdapter
def myFunction(apiRequestUrl: String, httpAdapter: HttpAdapter = HttpAdapter) : MyObject = {
val response: String = httpAdapter.fromUrl(apiRequestUrl)
val formatedResponse: MyObject = formatResponseFunction(response)
formatedResponse
}
"myFunction" should "work" in {
//create mock
val http = mock[HttpAdapter]
//stub mock
http.fromUrl("some url") shouldReturn "result"
//inject mock
myFunction("some url", http) shouldBe MyObject
}
注意,我已经将第三方API封装在我可以完全控制(HttpAdapter
)的类中,然后我模拟了那个
然后我将httpAdapter
作为参数注入,但是我提供了默认值,因此调用者不必担心它,尽管我仍然可以在测试代码中使用模拟或存根来覆盖它
还请注意,我使用的是Mockito-scala而不是常规的Mockito,因此存根语法是不同的