Mironor
Mironor

Reputation: 1187

Injecting dependencies in tests in Play framework with scaldi

I'm looking for a way to inject a dependency into a Test (in /tests/models/) that looks like following:

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
    }

  }
}

Where

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

/app/modules/WebModule:

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

/app/Global:

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

But at compilation time I have following stack trace:

[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)

Sadly, I didn't find anything on the matter in Scaldi documentation.

Is there a way to inject things in tests?

Upvotes: 2

Views: 1217

Answers (1)

tenshi
tenshi

Reputation: 26566

Scaldi does not provide an integration with any testing framework, but you actually normally don't need it. What you can do in this case is to create a test Module that contains mocks and stubs (like in-memory databases) and then just provide a test Global to the FakeApplication. Here is an example of how you can do it:

"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")
  }
}

You can find this code in the scaldi-play-example application.

Upvotes: 1

Related Questions