【问题标题】:How to Test a Play Application that extends a custom trait如何测试扩展自定义特征的 Play 应用程序
【发布时间】:2016-12-02 03:02:43
【问题描述】:

我在为我的 Play 应用程序的 mixin 编写测试时遇到了麻烦,该应用程序在它自己的线程中运行,与 play 分开。我尝试过重写WithApplication.provideApplication 方法,但没有成功。我收到inheriting conflicting methods 错误。 (一个来自真正的应用程序“MyRunnableSystemWrapper”,一个来自我的 mocked 假混入,名为“MyMockedSystemWrapper”)。

execute(system) 运行我的系统,该系统在其他地方进行了测试并且有副作用(连接到网络服务,因此当这些东西不可用时,此测试失败。好消息是我的系统包装器的模拟服务使用了一个系统没有副作用,并且数据库/网络调用被模拟出来。但是我不知道如何将我的应用程序的这个模拟版本提供给“WithApplication”测试。

为清晰起见简化代码:

class Application extends Controller with MyRunnableSystemWrapper {

  val pool: ExecutorService = Executors.newFixedThreadPool(1)
  val system = new MyRunnableSystem() //system is abstract in MRSW ^^^ above
  pool.execute(system)

  def index = Action {
    OK("HI")
  }
}

我的测试:

class MyAppTest(implicit ee: ExecutionEnv) extends Specification  {

  abstract class WithMyMockApp extends WithApplication {
    def provideApplication = new controllers.Application with MyMockedSystemWrapper // This imports MyRunnableSystemWrapper 

  }

  "Sending a GET request" should {
    "Respond with OK" in new WithMyMockApp {
      val response = route(app, FakeRequest(GET, "/")).get
      status(response) mustEqual OK
    }
  }
}

如果我没有在正确的位置运行我的 Runnable 并且应该在其他地方调用它以简化此测试,请告诉我!

【问题讨论】:

  • 我也想过像这样为我的系统创建一个自类型引用:class Application extends controller { mysys : MySystem => ...} 但是我不知道如何让 Play 知道使用某个依赖项。由于 play 会自动找到这个 Application Controller 并启动它,我如何在 Prod 和 Test 中给它我的 Mixin?
  • 我收到 com.google.inject.ProvisionException: Unable to provision 错误,因为 Play 不知道如何使用 MySystem 启动它。

标签: scala testing dependency-injection playframework specs2


【解决方案1】:

你可以注入你的系统包装而不是扩展它

trait SystemWrapper {
    def execute(system: RunnableSystem)
}

class MyRunnableSystemWrapper extends SystemWrapper {...}
class MyMockedSystemWrapper extends SystemWrapper {...}

class Application @Inject() (systemWrapper SystemWrapper) extends Controller {

然后你需要告诉 Guice 你想要哪个SystemWrapper 的实现用于运行时以及哪个用于测试。一种方法是使用您在 .conf 文件中设置的不同 Guice 模块进行运行时/测试。

【讨论】:

  • 我想这就是我要找的东西,但你在 .conf 中失去了我。你有.conf的例子吗?我已经设置了一个 test.conf 并且在测试期间正在使用它。谢谢!
  • 您可以在这里查看如何创建一个模块,然后在每个.conf 文件中选择要加载的模块playframework.com/documentation/2.5.x/…
  • 我在尝试 Inject 方式时得到了 No implementation for com.echostar.sse.meteor.models.Meteor.SystemComponent was bound.class prodSystem extends MeteorSystemComponent { rmqServiceFactory: RMQServiceFactory => val system = new MeteorSystem("Production") } class Application @Inject() (msc: Meteor.SystemComponent) extends Controller with Logging { 我现在将其命名为 prodSystem。根据错误消息,它不具有约束力。如何绑定两者?
  • 您可以在 Guice 模块中执行此操作,然后在 .conf 文件中启用:playframework.com/documentation/2.5.x/…
猜你喜欢
  • 1970-01-01
  • 2011-07-11
  • 2013-01-07
  • 2022-11-16
  • 1970-01-01
  • 2011-05-02
  • 2014-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多