Search code examples
scalaspec2

How to test an injected class through Spec2?


I am trying to test a class

@Singleton
class Foo @Inject()(bar: Bar)(implicit ec: ExecutionContext) {
  def doSomething = bar.doSomethingInBar
}

class Bar {
  def doSomethingInBar = true
}

through a Specification class that is mentioned below

class FooTest @Inject()(foo: Foo) extends Specification {
  "foo" should {
    "bar" in {
      foo.doSomething mustEqual (true)
    }
  }
}

Now when I run this I get the following error

Can't find a constructor for class Foo

I followed the solution mentioned here

And defined an Injector

object Inject {
  lazy val injector = Guice.createInjector()

  def apply[T <: AnyRef](implicit m: ClassTag[T]): T =
    injector.getInstance(m.runtimeClass).asInstanceOf[T]
}

and a lazy val foo: Foo = Inject[Foo] inside my Specification class. It solves my constructor initialization problem but I am getting this error now.

[error]   ! check the calculate assets function
[error]    Guice configuration errors:
[error]    
[error]    1) No implementation for scala.concurrent.ExecutionContext was bound.
[error]      while locating scala.concurrent.ExecutionContext

Solution

  • You need to provide an implicit ExecutionEnv to make the code work

    @RunWith(classOf[JUnitRunner])
    class FooTest(implicit ee: ExecutionEnv)  extends Specification {
      "foo" should {
        "bar" in {
          foo.doSomething mustEqual (true)
        }
      }
    }
    

    Now somewhere in your code, you need to initialize the foo construct and you can pass it through the constructor - which is the point of having dependency injection.