2016-08-01 6 views
1

Представьте меня есть служба:Тестирование блока с неявным классом в Scala

class ServiceA(serviceB: ServiceB) { 

    import Extractor._ 

    def send(typeA: A) = serviceB.send(typeA.extract) 

} 

object Extractor { 
    implicit class Extractor(type: A) { 
     def extract = ??? 
    } 
} 

Я хочу метод extract быть неявно определено, поскольку он не имеет прямого отношения к A типа/домен и является решением специальное расширение adhoc.

Теперь я хотел бы написать очень простой единичный тест, который подтверждает, что вызывается serviceB.send.

Для этого я высмеиваю service и передаю издевательство A по адресу send. Тогда я мог просто утверждать, что serviceB.send был вызван с насмешкой A.

Как видно из примера, метод send также выполняет некоторую трансформацию по параметру typeA, поэтому мне нужно было бы высмеять метод extract для возврата моего указанного значения. Однако A не имеет метода extract - он исходит от implicit class.

Итак, вопрос в том, как я высмеиваю неявный класс, как в приведенном выше примере, поскольку импорт не является гражданами первого сорта.

ответ

0

Если вы хотите задать кучу индивидуальных методов выписки, вы можете сделать что-то вроде этого:

sealed trait Extractor[T] { 
    // or whatever signature you want 
    def extract(obj: T): String 
} 
object Extractor { 

    implicit case object IntExtractor extends Extractor[Int] { 
    def extract(obj: Int): String = s"I am an int and my value is $obj" 
    } 
    implicit case object StringExtractor extends Extractor[String] { 
    def extract(obj: String): String = s"I am " 
    } 

    def apply[A : Extractor](obj: A): String = { 
    implicitly[Extractor[A]].extract(obj) 
    } 

} 

Итак, вы в основном закрытого типа семьи, который предварительно материализованный через корпус объекты, которые, возможно, только полезный в match. Но это позволит вам разделить все.

Если вы не хотите смешивать это с Extractor, назовите их чем-то другим и выполните тот же подход, затем вы можете смешать все это с привязкой к контексту.

Затем вы можете использовать это с:

println(Extractor(5)) 

Для тестирования, просто переопределить доступные implicits, если вам нужно. Немного работы, но не невозможно, вы можете просто управлять областью, и вы можете отслеживать любые вызовы методов, которые вы хотите.

например, вместо import Extractor._ есть другой объект с логикой только для тестирования, где вы можете использовать mocks или альтернативную реализацию.

Смежные вопросы