Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.2k views
in Technique[技术] by (71.8m points)

scala - ZIO Mock method that works with generics

I'm trying to mock a service that has a generic method but I can't figure out how to define the effect in the mock. Can a generic effect even work? Are there any workarounds?

The service:

object AService {

  type AService = Has[Service]

  trait Service {
    def add(n1: Int, n2: Int): Task[Int]
    def foo[A](n1: A, n2: A): Task[A]
  }

  def live: ULayer[Has[Service]] = ...
}

The mock:

object AServiceMock extends Mock[AService] {

  object Add        extends Effect[(Int, Int), Nothing, Int]
  object Foo[T]     extends Effect[(T, T), Nothing, T]       // <- Can I make something like this work?

  override protected[test] val compose = ZLayer.fromService {proxy =>
    new AService.Service {
      override def add(n1: Int, n2: Int): Task[Int] = proxy(Add, n1, n2)

      override def foo[T](n1: T, n2: T): Task[T] = proxy(Foo, n1, n2)
    }
  }
}

PS: I also tried with @mockable[AService.Service] but I receive: "exception during macro expansion: identifier expected but $XMLSTART$< found"

Thanks


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Solved. The answer was in the ZIO documentation

def foo[A: zio.Tag](n1: A, n2: A): Task[A]

----------------

object AServiceMock extends Mock[AService] {

  object Add extends Effect[(Int, Int), Nothing, Int]
  object Foo extends Poly.Effect.InputOutput[Nothing]

  val compose: URLayer[Has[mock.Proxy], AService] = ZLayer.fromService { proxy =>
    new AService.Service {
      override def add(n1: Int, n2: Int): Task[Int] = proxy(Add, n1, n2)

      override def foo[A: Tag](n1: A, n2: A): Task[A] = proxy(Foo.of[(A, A), A], n1, n2)
    }
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...