Last active
January 3, 2016 18:39
-
-
Save daimatz/8503238 to your computer and use it in GitHub Desktop.
Dependency Injection by Cake Pattern http://eed3si9n.com/ja/real-world-scala-dependency-injection-di
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class User(username: String, password: String) | |
trait UserRepositoryComponent { | |
val userRepository: UserRepository | |
// ordinal class | |
class UserRepository { | |
def authenticate(user: User): User = { | |
println("authenticating user: " + user) | |
user | |
} | |
def create(user: User) = println("creating user: " + user) | |
def delete(user: User) = println("deleting user: " + user) | |
} | |
} | |
trait UserServiceComponent { | |
// specify dependencies by self-type annotation | |
self: UserRepositoryComponent => | |
val userService: UserService | |
class UserService { | |
def authenticate(username: String, password: String): User = | |
userRepository.authenticate(new User(username, password)) | |
def create(username: String, password: String) = | |
userRepository.create(new User(username, password)) | |
def delete(user: User) = | |
userRepository.delete(user) | |
} | |
} | |
// for Production | |
trait RealEnvironment | |
extends UserServiceComponent | |
with UserRepositoryComponent | |
{ | |
val userRepository = new UserRepository | |
val userService = new UserService | |
} | |
object Main extends RealEnvironment { | |
def main(args: Array[String]) { | |
val user = userService.authenticate("foo", "bar") | |
println("authenticated user is " + user) | |
} | |
} | |
// for Test | |
import org.mockito._ | |
import org.specs2.mutable._ | |
trait TestEnvironment | |
extends UserServiceComponent | |
with UserRepositoryComponent | |
{ | |
// all dependant objects are mocked | |
val userRepository = Mockito.mock(classOf[UserRepository]) | |
val userService = Mockito.mock(classOf[UserService]) | |
} | |
class UserServiceSpec extends Specification with TestEnvironment { | |
// create a non-Mock object that you want to test | |
override val userService = new UserService | |
"authenticate" should { | |
"return user" in { | |
val user = User("test", "test") | |
// note that denpendant object `userRepository` is mocked | |
Mockito.when(userRepository.authenticate(user)).thenReturn(user) | |
userService.authenticate("test", "test") must_== user | |
} | |
} | |
} |
Author
daimatz
commented
Jan 19, 2014
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment