【问题标题】:Play: How to replace `Play.current` with DI? [duplicate]Play:如何用 DI 替换 `Play.current`? [复制]
【发布时间】:2017-02-11 07:42:21
【问题描述】:

在尝试编写测试时,我从 Play 收到此警告:

您在范围内没有隐式应用程序。如果您想将当前正在运行的应用程序带入上下文,请使用依赖注入。

我发现如果我添加这个导入,它神奇地解决了应用程序在范围内的问题:

import play.api.Play.current

但是它会警告你

不推荐使用对象 Play 中的当前方法:这是对应用程序的静态引用,请改用 DI

如何使用依赖注入来获得相同的结果?这是我需要它的地方:

class TestSpec extends PlaySpec with OneAppPerSuite { ... }

编辑:我确实找到了this post,但我不知道答案如何为我提供隐式 Application 的线索。

【问题讨论】:

  • 很大程度上取决于您要使用哪个 DI
  • 我猜是 Guice,如果这有意义的话。它应该作为依赖项插入与 Play.current 全局插入的等效项。
  • 您究竟需要current提供什么?
  • 好吧,警告说“您在范围内没有隐式应用程序”,所以我需要它。 ConfigurationEnvironment 都没有给我任何线索,让我知道如何处理它们以获得隐含的 Application。此外,如果我像在控制器中那样在TestSpec 中注入一些东西,测试就不再运行了。我虽然每个人都至少经历过一次同样的问题。

标签: scala playframework playframework-2.0


【解决方案1】:

我被指向this example(@insan-e),它展示了如何解决这个问题。你不能注入测试类,但你“只”需要用这个覆盖你的PlaySpec

import javax.inject.{Inject, Singleton}
import org.scalatestplus.play.{OneAppPerSuite, PlaySpec}
import play.api.Application
import play.api.inject.guice.GuiceApplicationBuilder

// To avoid repeating the `instanceCache` line below for each DAO
@Singleton
class DaoContext @Inject()(
                        val testDAO: TestDAO
                        // Other DAOs here
)

abstract class BetterSpec extends PlaySpec with OneAppPerSuite {
  implicit override lazy val app = new GuiceApplicationBuilder().configure(...).build

  protected def daoContext(implicit app: Application): DaoContext = {
    Application.instanceCache[DaoContext].apply(app)
  }
}

和测试:

class TestSpec extends BetterSpec {
  "Test DAO" should {
    "work" in {
      val dao = daoContext.testDAO
      // test it, finally
    }
  }
}

我知道,“这到底是什么????”但它奏效了。

注意现在它可以作为Play Slick: How to inject DbConfigProvider in tests的副本关闭

【讨论】:

    猜你喜欢
    • 2016-08-18
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 2014-01-25
    • 1970-01-01
    • 2020-01-06
    • 1970-01-01
    相关资源
    最近更新 更多