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