Reputation: 9319
In my Play 2.6.x application, I'm testing with PlaySpec
. Now I would like to inject some object to be used in test code.
class AuthControllerTest @Inject()(userRepository: UserRepository)
extends PlaySpec with GuiceOneAppPerSuite with Injecting {
"Foo bar" should {
"do xyz" in {
// do something with userRepository
}
}
}
However, this class never gets picked up for tests, e.g. when running sbt test
.
A simple workaround is to manually get the injector from the current Play instance, but Play.current
is deprecated and it generally feels hacky:
class AuthControllerTest
extends PlaySpec with GuiceOneAppPerSuite with Injecting {
"Foo bar" should {
"do xyz" in {
val userRepository = Play.current.injector.instanceOf[UserRepository]
// do something with userRepository
}
}
}
Why doesn't the former example work? And is there a cleaner approach than the latter example?
Upvotes: 3
Views: 783
Reputation: 12214
Play Framework does not do dependency injection for tests like the first example. On the second one, you don't need Play.current
since GuiceOneAppPerSuite
makes an Application (app
) available to you. So you can do:
val userRepository = app.injector.instanceOf[UserRepository].
And by using Injecting
, you can simplify it even further like:
val userRepository = inject[UserRepository]
And from the official docs:
If all or most tests in your test class need an Application, and they can all share the same instance of Application, mix in trait GuiceOneAppPerSuite with the GuiceFakeApplicationFactory trait. You can access the Application from the app field.
There is also a page about Injecting in the official docs.
Upvotes: 3