Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Example Cake and Play 2.0 ver 2
/*********************************************************
* Setup Domain object, repositories and service objects *
********************************************************/
// Identity.scala
case class Identity(id: Int = 0, var slug: String, var email: String, references: Symbol)
// IdentityRepostiory.scala: my interface that isolates concrete instances
trait IdentityRepository {
def findBySlug(slug: String): Option[Identity]
def findByEmail(email: String): Option[Identity]
def save(identity: Identity): Identity
}
// RepostioryFactory.scala: my repository factory trait, where implementers will return the real IdentityRepository
trait RepositoryFactory {
def identityRepository : IdentityRepository
}
// RepositoryFactoryImpl.scala a concrete implementation that returns my concrete IdentityRepository factory
trait RepositoryFactoryImpl extends RepositoryFactory {
val identityRepository = new IdentityRepositoryImpl
}
// IdentityService.scala: Basic interface that sets declare which operations are supported by my service
trait IdentityService {
def isSlugAvailable(name: String): Boolean
def findBySlug(name: String): Option[Identity]
}
// IdentityServiceImpl.scala: my concrete implementation of my IdentityService trait.
// It uses constructor injection to get the correct instance of the repository factory.
class IdentityServiceImpl(val repositoryFactory: RepositoryFactory) extends IdentityService {
def findBySlug(slug: String): Option[Identity] = repositoryFactory.identityRepository.findBySlug(slug)
def isSlugAvailable(name: String) = findBySlug(name) match {
case Some(_) => false
case None => true
}
}
// ServiceFactory.scala: the contract for my service object abstract factory
trait ServiceFactory {
this: RepositoryFactory => // sets up the cake pattern dependency on a repository factory
def identityService: IdentityService
}
// ServiceFactoryImpl.scala: my concrete implmenetation of the service factory. Which uses my concrete
// implementation of my repository factory
trait ServiceFactoryImpl extends ServiceFactory with RepositoryFactoryImpl {
def identityService: IdentityService = new IdentityServiceImpl(this)
}
/***************************************************************************
* Play 2.0 Application controller, where I'm setting up the dependencies! *
* package controllers *
**************************************************************************/
import play.api._
import play.api.mvc._
import impl._
import views.html.application.login
import libs.json._
trait ApplicationController extends Controller { // my controller declared as a trait with implementation
this: ServiceFactory => // wire dependency
def slugAvailable(slug:String) = Action {
val result = new JsObject(Seq(
"isAvailable" -> JsBoolean{
this.identityService.isSlugAvailable(slug) // use my service factory from the self type annotation
}
))
Ok(result)
}
}
// Create my Application object to be used by the Play framework, specifying my concrete Service Factory implementation
object Application extends ApplicationController with ServiceFactoryImpl
/***********************************
* Unit Testing: Configuring Mocks *
**********************************/
// MckServiceFactory.scala
trait MckServiceFactory extends Mockito with ServiceFactory { this: RepositoryFactory =>
val identityService: IdentityService = mock[IdentityService]
}
// MckRepositoryFactory.scala
trait MckRepositoryFactory extends Mockito with RepositoryFactory {
val identityRepository = mock[IdentityRepository]
}
/*********************************************
* Unit Testing: ApplicationController trait *
********************************************/
import org.specs2.mock.Mockito
import org.specs2.mutable.Specification
import play.api.test.Helpers._
import play.api.test.FakeRequest
import test.MckServiceFactory
import controllers.ApplicationController
import test.MckRepositoryFactory
class ApplicationSpec extends Specification with Mockito {
import controllers.ApplicationController // my controller trait
"Application.slugAvailable" should {
"""return {"isAvailable": true} when searching ghorsey""" in {
object controller extends ApplicationController with MckServiceFactory with MckRepositoryFactory {
identityService.isSlugAvailable("ghorsey") returns true
} // create my controller trait w/ my mocked service factory
val result = controller.slugAvailable("ghorsey")(FakeRequest())
status(result) mustEqual OK
contentType(result) must beSome("application/json")
contentAsString(result) mustEqual """{"isAvailable":true}"""
got {
one(controller.identityService).isSlugAvailable("ghorsey")
}
}
"""return {"isAvailable": false} when searching geoff""" in {
object controller extends ApplicationController with MckServiceFactory with MckRepositoryFactory {
identityService.isSlugAvailable("geoff") returns false
} // create my controller trait w/ my mocked service factory
val result = controller.slugAvailable("geoff")(FakeRequest())
status(result) mustEqual OK
contentType(result) must beSome("application/json")
contentAsString(result) mustEqual """{"isAvailable":false}"""
got {
one(controller.identityService).isSlugAvailable("geoff")
}
}
}
}

@ghorsey Exactly what I was looking for, even I was reading up on cake with play.
Only other thing that I now have is can we unit test our routers as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment