Specs2:如何测试具有多个注入依赖项的类?

Jon*_*nik 7 dependency-injection scala playframework specs2 playframework-2.4

玩2.4应用程序,使用服务类的依赖注入.

我发现当被测试的服务类具有多个注入依赖项时,Specs2会发生阻塞.它失败了" 找不到类的构造函数...... "

$ test-only services.ReportServiceSpec
[error] Can't find a constructor for class services.ReportService
[error] Error: Total 1, Failed 0, Errors 1, Passed 0
[error] Error during tests:
[error]         services.ReportServiceSpec
[error] (test:testOnly) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 2 s, completed Dec 8, 2015 5:24:34 PM
Run Code Online (Sandbox Code Playgroud)

生产代码,剥离到最低限度以重现此问题:

package services

import javax.inject.Inject

class ReportService @Inject()(userService: UserService, supportService: SupportService) {  
   // ...  
}

class UserService {  
   // ...  
}

class SupportService {  
   // ...  
}
Run Code Online (Sandbox Code Playgroud)

测试代码:

package services

import javax.inject.Inject

import org.specs2.mutable.Specification

class ReportServiceSpec @Inject()(service: ReportService) extends Specification {

  "ReportService" should {
    "Work" in {
      1 mustEqual 1
    }
  }

}
Run Code Online (Sandbox Code Playgroud)

如果我删除其中任何一个UserServiceSupportService依赖ReportService,测试工作.但显然,依赖关系在生产代码中是有原因的.问题是,我该如何使这项测试工作?

编辑:当尝试在IntelliJ IDEA中运行测试时,同样的事情失败了,但是有不同的消息:"测试框架意外退出","这看起来像specs2异常......"; 使用stacktrace查看完整输出.我按照输出中的说明打开了Specs2 问题,但我不知道问题是在Play还是Specs2或其他地方.

我的库依赖项如下.(我试过指定Specs2版本明确,但是这并没有帮助.看起来我需要specs2 % Test的,对于游戏的测试类喜欢WithApplication的工作.)

resolvers += "scalaz-bintray" at "https://dl.bintray.com/scalaz/releases"
libraryDependencies ++= Seq(
  specs2 % Test,
  jdbc,
  evolutions,
  filters,
  "com.typesafe.play" %% "anorm" % "2.4.0",
  "org.postgresql" % "postgresql" % "9.4-1205-jdbc42"
)
Run Code Online (Sandbox Code Playgroud)

Eri*_*ric 8

在specs2中对依赖注入的支持有限,主要用于执行环境或命令行参数.

没有什么可以阻止你只使用一个lazy val和你最喜欢的注射框架:

class MySpec extends Specification with Inject {
  lazy val reportService = inject[ReportService]

  ...
}
Run Code Online (Sandbox Code Playgroud)

使用Play和Guice,您可以拥有一个测试助手,例如:

import play.api.inject.guice.GuiceApplicationBuilder
import scala.reflect.ClassTag    

trait Inject {
  lazy val injector = (new GuiceApplicationBuilder).injector()

  def inject[T : ClassTag]: T = injector.instanceOf[T]
}
Run Code Online (Sandbox Code Playgroud)