ScalaMock icon indicating copy to clipboard operation
ScalaMock copied to clipboard

Overloaded method cannot be mocked if one of its parameters is a generic available to the trait.

Open pawel-wiejacha opened this issue 10 years ago • 7 comments

reported by @trane in #39:

trait OverloadedMultiParams[A] {
  def meth(i: Int, a: A): Int
  def meth(): Int
}

val mockTrait = mock[OverloadedMultiParams[String]]
(mockTrait.meth(_: Int, _: String)).expects(1, "Hello").returns(1)

Returns:

Information:(74, 20) Unable to resolve overloaded method meth
    (mockTrait.meth(_: Int, _: String)).expects(1, "Hello").returns(1)
                   ^

pawel-wiejacha avatar Feb 03 '15 22:02 pawel-wiejacha

Using scalamock v4.1.0 with scalatestplus-play v3.1.2:


trait Foo[T] {
  def create(bar: T)
  def create(bar: Seq[T])
}

trait Bar extends Foo[User]

val userApi = mock[Bar]
(userApi.create(_: User)).expects(User("John"))

Getting compile error: value expects is not a member of ....

@pawel-wiejacha Interestingly, if I remove def create(bar: Seq[T]) from the Foo trait, it compiles.

vmandrychenko avatar Sep 04 '18 19:09 vmandrychenko

Still struggling with it on ScalaMock 5.1.0, ScalaTest 3.2.7, and Scala 2.13.6.

Is there any known workaround for this problem? I try to stub the http4s Client trait without any success due to this issue.

jdsee avatar Jul 10 '21 01:07 jdsee

What you can try is to not use a trait with a parameter. So instead of


trait Foo[T] {
  def create(bar: T)
  def create(bar: Seq[T])
}

try


trait IntFoo {
  def create(bar: Int)
  def create(bar: Seq[Int])
}

and then subsequently mock IntFoo

barkhorn avatar Jul 11 '21 06:07 barkhorn

I've run into this problem while trying to mock org.http4s.Client[F[_]]'s expect method:

val clientMock    = mock[Client[IO]]
val intentDecoder = IntentDecoder.impl(clientMock)
val requestBody   = ARequest(a = "1234", b = "Hello")
val ApiKey        = "REDACTED"

(clientMock.expect[AResponse](_: Request[IO])(_: EntityDecoder[IO, AResponse]))
  .expects(
    Request[IO](
      POST,
      uri"https://redacted.com/api/intents",
      headers = Headers(List(Header.Raw(ci"Authentication", ApiKey)))
    ).withEntity(requestBody.asJson),
    *
  ).returning(AResponse("Some result").pure[IO])

This too results in:

Unable to resolve overloaded method expect
      .expect[AResponse](_: Request[IO])(_: EntityDecoder[IO, AResponse]))

LukeKeywalker avatar Aug 14 '22 20:08 LukeKeywalker

Still experiencing this issue when trying to mock a RBucket[String] (from redisson library) with scalamock version 5.2.0, scala 2.13.10 and specs2-core 4.16.0.

In my case the suggested above workaround didn't work, here is what I tried:

trait RBucketString extends RBucket[String]

...
val mockRBucket = mock[RBucketString]
...
(mockRBucket.setAsync(_: String)).expects(*).returns...

I get a compilation error:

value expects is not a member of String => org.redisson.api.RFuture[Void]

vasigorc avatar Dec 20 '22 17:12 vasigorc

I'm encountering what I suspect is the same issue trying to mock StatsDClient from https://github.com/DataDog/java-dogstatsd-client

  • Scala 2.13.10
  • Scalatest 3.2.15
  • Scalamock: 5.2.0
  • java-dogstatsd-client: 4.2.0

I am trying to mock void incrementCounter(String aspect, String... tags);.

datadogClient.incrementCounter(_: String, _: String)).expects(*).anyNumberOfTimes()

fails with value expects is not a member of (String, String) => Unit.

Why do I think this might be the same issue? incrementCounter is overloaded and there is also void incrementCounter(String aspect, double sampleRate, String... tags);

sacsar avatar Apr 11 '23 01:04 sacsar

Works with scala 3

goshacodes avatar Feb 25 '24 10:02 goshacodes