【发布时间】:2013-06-17 18:24:52
【问题描述】:
假设我正在测试一个方法,它依赖于一个名为 WS(Web 服务)的(导入的)单例实例,它有一个方法 url(url:String),它接受一个 URL并返回一个请求。
def doRequest(url: String): Future[Response] = {
val request = WS.url(url)
for {
response <- request.post(params)
} yield {
val res: JsResult[MyResult] = response.json.validate[MyResult]
res.getOrElse(throw new NotSupportedException)
}
}
我希望能够注入 WS 依赖项,这样我的单元测试就不需要实际的出站 http 请求,而是可以依赖于模拟 WS 实例。
这对我来说是一个挑战,因为虽然单例在技术上确实有一个类型 (Class[WS.type]),但是在将单例绑定到 val 时,WS 的属性和方法会丢失它需要一个类 [WS.type]。这意味着我不能像这样简单地使用简单的蛋糕图案:
trait WSComponent {
val ws: Class[_ <: WS.type]
}
object ApplicationContext extends WSComponent {
val ws = WS
}
object TestContext extends WSComponent {
val ws = mock[WS]
}
如果我这样做,然后在任一上下文中调用 WS 的方法,我会收到一个编译错误,即 Class[_ <: ws.type>
出于类似的原因(基本上,单例对象没有类型——即使它们有——),我不能提供一个采用 WS.type 的隐式参数,因为我又会输在单例对象上声明的方法和属性。
有哪些方法可以在单例对象上注入依赖项?我喜欢在 DI 中使用 cake 模式,但它在我的代码中引入了相当多的样板,因此理想的解决方案不会将代码与过多的样板混合在一起。
提前感谢您的任何建议。
【问题讨论】:
-
你怎么能有
val ws: Class[_ <: WS.type]和一个子类型val ws = WS?你不是说val ws: WS.type吗?
标签: unit-testing scala dependency-injection playframework-2.0 scalatest