I have a implicit class which requires a user database. I want to use self-type in implicit class so I can switch implementation of database in testing scope to the mocked version. How do I mix-in database provider in this case? For example, I want user of RuchUser to not worry about having to mix-in UserDatabaseProvider by providing default mix-in. So user can just do User("name").userContext
and do the same at testing scope where I will provide default mix-in to use mocked database provider?
case class User(name: String)
object User {
implicit class RichUser(self: User) { this: UserDatabaseProvider =>
def userContext: String = this.getUserContext(self.name)
}
}
// Usage of Rich user should be below as I want to provide already mixed-in implicit
import User._
val context = User("name").uerContext
I think you are overcomplicating quite a bit.
case class User(name: String) {
def context()(implicit db: UserDatabaseProvider): UserContext = {
db.getUserContext(name)
}
}
I would go to further suggest the cake pattern may be more applicable here than using implicits.
class UserService extends UserDatabaseProvider {
def context(user: User): UserContext = getUserContext(user.name)
}
class TestUserService extends UserService with TestDatabase
Let "right-most wins" diamond resolution in Scala do the job for you.