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

Mocking tagged types fails in Scala 3 #545

Open
arteme opened this issue Nov 4, 2024 · 1 comment
Open

Mocking tagged types fails in Scala 3 #545

arteme opened this issue Nov 4, 2024 · 1 comment

Comments

@arteme
Copy link

arteme commented Nov 4, 2024

If you want to discuss a new feature, please ignore/clear this form.

ScalaMock Version (e.g. 3.5.0)

6.0.0

Scala Version (e.g. 2.12)

3.4.2

Runtime (JVM or JS)

JVM

Please describe the expected behavior of the issue

Consider the following code:

import org.scalamock.scalatest.MockFactory
import org.scalatest.TestSuite

// macwire tagging
trait Tag[+U] extends Any { type Tag <: U }
type @@[+T,+U] = T with Tag[U]

implicit class Tagger[T](val t: T) extends AnyVal {
  @inline def taggedWith[U]: T @@ U = t.asInstanceOf[T @@ U]
}

// example
case class CacheApi()
trait SettingsCache
trait DataCache

case class Controller(settingsCache: CacheApi @@ SettingsCache)

// how this may be used in the real app
object RealContext {  
  val settingsCache: CacheApi @@ SettingsCache = CacheApi().taggedWith[SettingsCache] 
  val dataCache: CacheApi @@ DataCache = CacheApi().taggedWith[DataCache]
  val contoller = Controller(settingsCache)
}

// how this is used in tests
trait TestContext extends MockFactory {
  this: TestSuite =>
  
  val controller = mock[Controller]
}

This code correctly mocks Controller in Scala 2.13, but fails in Scala 3 with a message:

Found:    @@
Required: CacheApi @@ SettingsCache

Scala 3 playground: https://scastie.scala-lang.org/mrSdYwvmSi2yz9daKC4neA
Scala 2.13 playground: https://scastie.scala-lang.org/jv7RKjqtTV2FUycZyME6MQ

@goshacodes
Copy link
Contributor

goshacodes commented Nov 5, 2024

Hi, thank you for reporting. It surely was supported in scala 2, but I'm not sure it should be fixed for scala 3, IMO you are doing something wrong.
You should mock interfaces not implementations.
Consider using Dependency Inversion principle and make your implementations depend on interfaces. It will make your test cases simpler and life easier.

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