imagine have service:
class servicea(serviceb: serviceb) { import extractor._ def send(typea: a) = serviceb.send(typea.extract) } object extractor { implicit class extractor(type: a) { def extract = ??? } }
i want extract
method implicitly defined because doesn't directly relate a
type/domain , solution specific adhoc extension.
now write simple unit test confirms serviceb.send
called.
for that, mock service
, pass mocked a
send
. assert serviceb.send
called mocked a
.
as seen in example, send
method transformation on typea
parameter need mock extract
method return specified value. however, a
doesn't have extract
method - comes implicit class
.
so question - how mock out implicit class in example above imports not first class citizens.
if want specify bunch of customised extract methods, can this:
sealed trait extractor[t] { // or whatever signature want def extract(obj: t): string } object extractor { implicit case object intextractor extends extractor[int] { def extract(obj: int): string = s"i int , value $obj" } implicit case object stringextractor extends extractor[string] { def extract(obj: string): string = s"i " } def apply[a : extractor](obj: a): string = { implicitly[extractor[a]].extract(obj) } }
so have sealed type family that's pre-materialised through case objects, arguably useful in match
. let decouple everything.
if don't want mix extractor
, call them else , follow same approach, can mix in context bound.
then can use with:
println(extractor(5))
for testing, override available implicits if need to. bit of work, not impossible, can control scope , can spy on whatever method calls want.
e.g instead of import extractor._
have other object test logic can use mocks or alternative implementation.
Comments
Post a Comment