2016-08-01 43 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并通过嘲讽Asend。然后我可以断言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) 
    } 

} 

所以你基本上是一个密闭型家族的pre-物化通过个案对象,只可以说是在match有用。但那会让你解开一切。

如果您不想与Extractor混合使用,请将它们称为其他内容并遵循相同的方法,然后您可以将其与上下文绑定混合。

然后你就可以使用这项功能:

println(Extractor(5)) 

为了测试,只需覆盖可用implicits如果您需要。有点工作,但不是不可能的,你可以简单地控制范围,你可以监视任何你想要的方法。

例如,而不是import Extractor._有一些其他对象,只测试逻辑,您可以使用模拟或替代实现。