有许多不同的方法可以做到这一点。
如果您DeadboltHandler
为访问主题注入了 DAO,则可以覆盖 DAO 的绑定以提供一个包含测试主题的对象。
abstract class AbstractControllerSpec extends PlaySpecification {
sequential
isolated
def testApp: Application = new GuiceApplicationBuilder().in(Mode.Test).bindings(bind[SubjectDao].to[TestSubjectDao]).build()
}
有关使用此方法的示例,请参阅测试应用程序。
或者,您可以扩展您的DeadboltHandler
实现以覆盖getSubject
并从此处提供测试主题。绑定的处理方式与上述相同。
最后,您可以保持所有代码原样并使用主题填充测试数据库;您发送的请求将取决于您的身份验证要求(标头、cookie 中的内容等)。
对于单元测试,类似的情况也适用。给定一个SubjectDao
具有一些用于测试目的的硬编码主题,您可以使用WithApplication
一个注入器查找来获得您需要的内容。
class TestSubjectDao extends SubjectDao {
val subjects: Map[String, Subject] = Map("greet" -> new SecuritySubject("greet",
List(SecurityRole("foo"),
SecurityRole("bar")),
List(SecurityPermission("killer.undead.zombie"))),
"lotte" -> new SecuritySubject("lotte",
List(SecurityRole("hurdy")),
List(SecurityPermission("killer.undead.vampire"))),
"steve" -> new SecuritySubject("steve",
List(SecurityRole("bar")),
List(SecurityPermission("curator.museum.insects"))),
"mani" -> new SecuritySubject("mani",
List(SecurityRole("bar"),
SecurityRole("hurdy")),
List(SecurityPermission("zombie.movie.enthusiast"))),
"trippel" -> new SecuritySubject("trippel",
List(SecurityRole("foo"),
SecurityRole("hurdy")),
List[SecurityPermission]()))
override def user(userName: String): Option[Subject] = subjects.get(userName)
}
使用看起来像这样的控制器:
class Subject @Inject()(deadbolt: DeadboltActions) extends Controller {
def subjectMustBePresent = deadbolt.SubjectPresent()() { authRequest =>
Future {
Ok("Content accessible")
}
}
}
然后我们可以像这样对它进行单元测试:
import be.objectify.deadbolt.scala.DeadboltActions
import be.objectify.deadbolt.scala.test.controllers.composed.Subject
import be.objectify.deadbolt.scala.test.dao.{SubjectDao, TestSubjectDao}
import play.api.Mode
import play.api.inject._
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.mvc.{Result, Results}
import play.api.test.{FakeRequest, PlaySpecification, WithApplication}
import scala.concurrent.Future
object SubjectPresentUnitSpec extends PlaySpecification with Results {
"Subject present " should {
"should result in a 401 when no subject is present" in new WithApplication(new GuiceApplicationBuilder().in(Mode.Test).bindings(bind[SubjectDao].to[TestSubjectDao]).build()) {
val deadbolt: DeadboltActions = implicitApp.injector.instanceOf[DeadboltActions]
val controller = new Subject(deadbolt)
val result: Future[Result] = call(controller.subjectMustBePresent(), FakeRequest())
val statusCode: Int = status(result)
statusCode must be equalTo 401
}
"should result in a 200 when a subject is present" in new WithApplication(new GuiceApplicationBuilder().in(Mode.Test).bindings(bind[SubjectDao].to[TestSubjectDao]).build()) {
val deadbolt: DeadboltActions = implicitApp.injector.instanceOf[DeadboltActions]
val controller = new Subject(deadbolt)
val result: Future[Result] = call(controller.subjectMustBePresent(), FakeRequest().withHeaders(("x-deadbolt-test-user", "greet")))
val statusCode: Int = status(result)
statusCode must be equalTo 200
}
}
}