2

I moved my unit tests from :

class UserSpec extends PlaySpec with OneAppPerTest with BeforeAndAfter with AsyncAssertions
{

To :

class UserSpec @Inject() (implicit exec: ExecutionContext, db: DBConnectionPool)
  extends PlaySpec with OneAppPerTest with BeforeAndAfter with AsyncAssertions
{

Everything was ok with the first version, but now, when I launch tests, I get the following result :

[info] No tests were executed.
[success] Total time: 4 s, completed Dec 5, 2016 8:35:24 PM

Note that I don't really want my tests to run with the same dependency injected in both tests and production. Thanks !

EDIT

Code available on github

Community
  • 1
  • 1
Moebius
  • 6,242
  • 7
  • 42
  • 54
  • can you provide the code? is hard to guess like this. share the project structure also – pedrorijo91 Dec 05 '16 at 20:16
  • Possible duplicate of [Specs2: how to test a class with more than one injected dependency?](http://stackoverflow.com/questions/34159857/specs2-how-to-test-a-class-with-more-than-one-injected-dependency) – rethab Dec 05 '16 at 20:17
  • OneAppPerTest, AsyncAssertions and BeforeAndAfter are scalatest related traits. This is not a specs2 question. – alextsc Dec 05 '16 at 20:22
  • @pedrorijo91 the complete code is here https://github.com/gbersac/electricity_manager – Moebius Dec 05 '16 at 20:25

2 Answers2

3

You don't use constructor injection when writing Play tests with scalatest. Instead you have access to the injector directly within the app.injector field when mixing in a server or app trait (such as your OneAppPerTest). This way you can inject a field into your test suite if you need anything from the DI graph:

val example = app.injector.instanceOf[Example]

So your initial code is the correct approach, mixed with using the injector directly. It could look similar to this:

class UserSpec extends PlaySpec with OneAppPerSuite 
               with BeforeAndAfter with AsyncAssertions {

  implicit val exec : ExecutionContext = app.injector.instanceOf[ExecutionContext]
  val db : DBConnectionPool = app.injector.instanceOf[DBConnectionPool]

  // ...

}

As far as customizing your DI bindings for tests goes, you can override them by customizing your app instance via the GuiceApplicationBuilder, see Creating Application Instances for Testing and Testing with Guice.

alextsc
  • 1,368
  • 1
  • 8
  • 13
  • Thanks, now it compile, but when I run test, I get the following error : ` Exception encountered when attempting to run a suite with class name: org.scalatest.DeferredAbortedSuite` `java.lang.NullPointerException:` at the line of `app.injector.asInstaceOf`. Any idea on how to solve it please ? – Moebius Dec 05 '16 at 20:47
  • It's `instanceOf`, not `asInstanceOf` (that's for casting - and you got a typo there too). Thats probably the problem. – alextsc Dec 05 '16 at 20:52
  • Thanks, I used `instanceOf`. Still have the problem. You can reproduce the error by cloning this repo : https://github.com/gbersac/electricity_manager/tree/dependencyInjection and checkout to `dependencyInjection`. – Moebius Dec 05 '16 at 20:59
  • 1
    Thanks a lot, but I just found the solution. You've been very helpfull and you helped me get to the right solution, but the answer to my problem was to add `override def newAppForTest(td: TestData) = new GuiceApplicationBuilder().build()` at the beginning of my spec suite. See example here : https://github.com/gbersac/electricity_manager/blob/master/test/UserSpec.scala – Moebius Dec 05 '16 at 21:40
0

When you test a class which need dependency injection, this classes need an application which inject object into those classes. In test, you have to manually create this application. Do it by adding the following line at the beginning of your test suite :

import play.api.inject.guice.GuiceApplicationBuilder
class UserSpec extends PlaySpec with OneAppPerTest with BeforeAndAfter with AsyncAssertions {
  override def newAppForTest(td: TestData) = new GuiceApplicationBuilder().build()
  [...]

Note that you can modify this application with special conf for tests. See the play documentation for more details.

The application I created for this case tiny and open source. See it for more details on how I implemented this : https://github.com/gbersac/electricity_manager

Moebius
  • 6,242
  • 7
  • 42
  • 54