如果使用注入,PlaySpec 测试 class 未获得

PlaySpec test class not picked up if using injection

在我的 Play 2.6.x 应用程序中,我正在使用 PlaySpec 进行测试。现在我想注入一些要在测试代码中使用的对象。

class AuthControllerTest @Inject()(userRepository: UserRepository)
  extends PlaySpec with GuiceOneAppPerSuite with Injecting {

  "Foo bar" should {
    "do xyz" in {
      // do something with userRepository
    }
  }
}

但是,这个 class 从来没有被拿来进行测试,例如当 运行 sbt test.

一个简单的解决方法是从当前的 Play 实例中手动获取注入器,但是 Play.current 已被弃用并且通常感觉很糟糕:

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

为什么前面的例子不起作用?还有比后一个例子更简洁的方法吗?

Play Framework 不会像第一个示例那样对测试进行依赖注入。在第二个上,您不需要 Play.current,因为 GuiceOneAppPerSuite 为您提供了一个应用程序 (app)。所以你可以这样做:

val userRepository = app.injector.instanceOf[UserRepository].

并且通过使用 Injecting,您可以进一步简化它,例如:

val userRepository = inject[UserRepository]

并且来自 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.

官方文档中也有关于Injecting的页面。