Hi,
I am working at the moment on a small lift demo app and I've added
some enhancements to specs in order to ease the testing inside a
session.
To use those functionalities, you need specs-1.6.1-SNAPSHOT (http://
www.scala-tools.org/repo-snapshots/org/scala-tools/testing/specs/1.6.1-SNAPSHOT).
Here are the specification and traits that I use to test the JPA
requests to save a User in the database:
// First I create Mocks for the lift session
import javax.servlet.http._
import net.liftweb.http.{ S, Req, LiftSession }
import org.specs.mock.Mockito
trait MockRequest extends Mockito { this: Specification =>
var request = mock[Req]
var httpRequest = mock[HttpServletRequest]
var session = mock[LiftSession]
def createMocks: Unit = {
request = mock[Req]
httpRequest = mock[HttpServletRequest]
session = mock[LiftSession]
request.request returns httpRequest
}
// this method can be used to executed any action inside a mocked
session
def inSession(f: =>Any) { S.init(request, session) { f } }
def unsetParameter(name: String) { request.param(name) returns
None }
def setParameter(name: String, value: String) { request.param
(name) returns Some(value) }
}
// Context creation for the specification
//
// This "Specification context" specifies the User table must be
cleaned up before each example.
// It also makes sure that the example expectations are executed in a
mocked session
// see
http://code.google.com/p/specs/wiki/DeclareSpecifications#Specification_context_(_from_1.6.1_)
for more information
object DatabaseContext extends Specification with Contexts with
MockRequest {
val setup = new SpecContext {
beforeExample(inSession(Users.createQuery("delete
User").executeUpdate)) // delete the User table before each example
aroundExpectations(inSession(_)) // execute each example inside a
mocked session
}
}
// and finally the specification itself
import org.specs._
import org.specs.specification._
class UserSpec extends SpecificationWithJUnit with MockRequest with
Contexts {
DatabaseContext.setup(this) // set the specification context on this
specification
"A Users repository" can {
"create a user" in {
val eric = User("etorreborre", "password", "Eric")
Users.mergeAndFlush(eric) // the Users object is a LocalEMF
with RequestVarEM so it needs a session
Users.find(classOf[User], "etorreborre") must_== Some(eric)
}
}
"A Users repository" should {
"throw an exception if the user name has a length < 5" in {
Users.merge(User("e", "password", "Eric")) must throwAn
[Exception]
}
}
}
I hope this helps too, please ask if you have any questions.
Eric.