Предположим, я тестирую метод, который зависит от (импортированного) одноэлементного экземпляра с именем WS (веб-служба), у которого есть метод 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]), свойства и методы WS теряются при привязке синглтона к val, который ожидает Класс[WS.тип]. Это означает, что я не могу просто использовать простой шаблон торта, например:
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] не имеет метода с именем (например) url().
По похожей причине (по сути, одноэлементные объекты не имеют типов, хотя они и есть), я не могу предоставить неявный параметр, который принимает WS.type, потому что, опять же, я потеряю методы и свойства, которые были объявлены для одноэлементного объекта.
Какие существуют подходы для внедрения зависимостей в одноэлементные объекты? Мне нравится использовать шаблон торта для внедрения зависимостей, но он вносит в мой код довольно много шаблонов, поэтому идеальное решение не будет смешивать код со слишком большим количеством шаблонов.
Заранее благодарим вас за любые предложения.
val ws: Class[_ <: WS.type]
и в подтипеval ws = WS
? Вы имеете в видуval ws: WS.type
? - person gourlaysama   schedule 20.06.2013