使用scaldi在Play框架中的测试中注入依赖项

时间:2014-10-20 19:34:12

标签: scala playframework scaldi

我正在寻找一种方法将依赖项注入到Test中(在/ tests / models /中),如下所示:

class FolderSpec(implicit inj: Injector) extends Specification with Injectable{

  val folderDAO = inject [FolderDAO]

  val user = User(Option(1), LoginInfo("key", "value"), None, None)

  "Folder model" should {

    "be addable to the database" in new WithFakeApplication {
      folderDAO.createRootForUser(user)
      val rootFolder = folderDAO.findUserFolderTree(user)
      rootFolder must beSome[Folder].await
    }

  }
}

其中

abstract class WithFakeApplication extends WithApplication(FakeApplication(additionalConfiguration = inMemoryDatabase()))

/应用程序/模块/ WebModule:

class WebModule extends Module{
  bind[FolderDAO] to new FolderDAO
}

/应用/全球:

object Global extends GlobalSettings with ScaldiSupport with SecuredSettings with Logger {
  def applicationModule = new WebModule :: new ControllerInjector
}

但是在编译时我有以下堆栈跟踪:

[error] Could not create an instance of models.FolderSpec
[error]   caused by java.lang.Exception: Could not instantiate class models.FolderSpec: argument type mismatch
[error]   org.specs2.reflect.Classes$class.tryToCreateObjectEither(Classes.scala:93)
[error]   org.specs2.reflect.Classes$.tryToCreateObjectEither(Classes.scala:207)
[error]   org.specs2.specification.SpecificationStructure$$anonfun$createSpecificationEither$2.apply(BaseSpecification.scala:119)
[error]   org.specs2.specification.SpecificationStructure$$anonfun$createSpecificationEither$2.apply(BaseSpecification.scala:119)
[error]   scala.Option.getOrElse(Option.scala:120)

可悲的是,我在Scaldi文档中找不到任何关于此事的内容。

有没有办法在测试中注入东西?

1 个答案:

答案 0 :(得分:1)

Scaldi不提供与任何测试框架的集成,但实际上您通常不需要它。在这种情况下,您可以做的是创建一个包含模拟和存根(如内存数据库)的测试Module,然后只为Global提供测试FakeApplication。以下是如何执行此操作的示例:

"render the index page" in {
  class TestModule extends Module {
    bind [MessageService] to new MessageService {
      def getGreetMessage(name: String) = "Test Message"
    }
  }

  object TestGlobal extends GlobalSettings with ScaldiSupport {

    // test module will override `MessageService`
    def applicationModule = new TestModule :: new WebModule :: new UserModule
  }

  running(FakeApplication(withGlobal = Some(TestGlobal))) {
    val home = route(FakeRequest(GET, "/")).get

    status(home) must equalTo(OK)
    contentType(home) must beSome.which(_ == "text/html")

    println(contentAsString(home))

    contentAsString(home) must contain ("Test Message")
  }
}

您可以在scaldi-play-example application

中找到此代码