I have the following class:
class LinkUserService() {
//** cake pattern **
oauthProvider: OAuthProvider =>
//******************
def isUserLinked(userId: String, service: String) = {
val cred = oauthProvider.loadCredential(userId)
cred != null
}
def linkUserAccount(userId: String, service: String): (String, Option[String]) = {
if (isUserLinked(userId, service)) {
("SERVICE_LINKED", None)
} else {
val authUrl = oauthProvider.newAuthorizationUrl
("SERVICE_NOT_LINKED", Some(authUrl))
}
}
def setLinkAuthToken(userId: String, service:String, token:String):String = {
oauthProvider.createAndStoreCredential(userId, token)
}
}
Typically I'd use this class in production like so:
val linkService = LinkUserService with GoogleOAuthProvider
When it comes to testing, I want to replace the oauthProvider
with a mock such that's been trained by my unit test to respond like so: oauthProvider.loadCredential("nobody") returns null
. Is this possible? If so, how would I set up my unit test to do so?
You have this problem because you are not using cake pattern to full extent. If you write something like
And then you use a mock like this:
Then your problem disappears. If you also make generic interface traits like this (and make other components depend on interface, not on implementation):
then you also would have generic reusable and testable code.
This is very similar to your suggestion and it really is the essence of cake pattern.