Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type mismatch trying to mock Future #296

Closed
steinybot opened this issue Feb 28, 2020 · 3 comments
Closed

Type mismatch trying to mock Future #296

steinybot opened this issue Feb 28, 2020 · 3 comments

Comments

@steinybot
Copy link

steinybot commented Feb 28, 2020

ScalaMock Version (e.g. 3.5.0)

4.4.0

Scala Version (e.g. 2.12)

2.13

Runtime (JVM or JS)

JVM

Please describe the expected behavior of the issue

This should compile:

    val future = stub[Future[Int]]
    (future.ready(_: Duration)(_: CanAwait)).when(*, *).throws(new TimeoutException("timeout")).once()
    (future.ready(_: Duration)(_: CanAwait)).when(*, *).returns(future).once()

Please provide a description of what actually happens

It fails with:

[error]  found   : scala.concurrent.Future[U(in method fallbackTo)]
[error]  required: scala.concurrent.Future[(some other)U(in method fallbackTo)]
[error]     val future = stub[Future[Int]]
[error]                      ^

I'm guessing maybe there is something in the macro causing it not to like this method:

trait Future[+T] extends Awaitable[T] {
  def fallbackTo[U >: T](that: Future[U]): Future[U] = ...
}

Reproducible Test Case

See above. Let me know if you need more details.

@steinybot
Copy link
Author

steinybot commented Feb 28, 2020

I get a little bit further if instead of stub[Future[Int]] I use stub[MockableFuture[Int]] but then I hit the next problem which is with a method that returns the Singleton Type (this.type):

  private trait MockableFuture[A] extends Future[A] {

    final override def fallbackTo[U >: A](that: Future[U]): Future[U] =
      super.fallbackTo(that)

    final override def recoverWith[U >: A](
        pf: PartialFunction[Throwable, Future[U]]
      )(implicit executor: ExecutionContext
      ): Future[U] = super.recoverWith(pf)

    final override def recover[U >: A](
        pf: PartialFunction[Throwable, U]
      )(implicit executor: ExecutionContext
      ): Future[U] =
      super.recover(pf)
  }

Which fails with:

[error] def ready(atMost: scala.concurrent.duration.Duration)(implicit permit: scala.concurrent.CanAwait): com.lightbend.console.hedgehog.implicits.FutureSyntaxSpec.$anon.type (defined in trait Awaitable);
[error]  found   : (atMost: scala.concurrent.duration.Duration)(implicit permit: scala.concurrent.CanAwait)MockableFuture.this.type (with underlying type (atMost: scala.concurrent.duration.Duration)(implicit permit: scala.concurrent.CanAwait)MockableFuture.this.type)
[error]  required: (atMost: scala.concurrent.duration.Duration)(implicit permit: scala.concurrent.CanAwait)com.lightbend.console.hedgehog.implicits.FutureSyntaxSpec.$anon.type
[error]     val future = stub[MockableFuture[Int]]
[error]                      ^

@barkhorn
Copy link
Collaborator

Hi @steinybot , this looks pretty much the same to me as #170 (you worked around it), and second #209 . Unfortunately both of these are still pending a solution at the moment and have been open for a while.

@barkhorn
Copy link
Collaborator

closing as duplicate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants