文档

§使用编译时依赖注入进行测试

如果您正在手动连接应用程序或使用 编译时依赖注入,那么您可以直接使用和自定义应用程序组件,或者创建特定于测试用例的测试变体。您还可以修改和覆盖过滤器、定义路由以及指定配置。

§BuiltInComponentsFromContext

BuiltInComponentsFromContext 为我们提供了一种轻松引导组件的方法。在给定上下文的情况下,它提供了所有必需的内置组件:environmentconfigurationapplicationLifecycle 等。

编译时依赖注入 中所述,这是手动连接应用程序最常见的方式。

在测试时,我们可以使用真实组件,这使我们能够启动完整的应用程序以进行完整的功能测试,或者我们可以创建测试组件,这些组件根据需要启动应用程序的子集。

§WithApplicationComponents

测试组件的关键是 WithApplicationComponents 特征。它设置了应用程序、服务器和上下文,准备进行测试。根据您的测试策略,可以使用许多可供混合的子特征
* OneAppPerSuiteWithComponents
* OneAppPerTestWithComponents
* OneServerPerSuiteWithComponents
* OneServerPerTestWithComponents

建议您熟悉每个特征的文档,以便决定哪个最适合您的需求。

§在代码中定义组件

如上所述,可以在测试中直接定义组件。为此,只需覆盖组件并完成 BuiltInComponentsFromContext 的实现,并提供路由器。

override def components: BuiltInComponents = new BuiltInComponentsFromContext(context) with NoHttpFiltersComponents {

  import play.api.mvc.Results
  import play.api.routing.Router
  import play.api.routing.sird._

  lazy val router: Router = Router.from({
    case GET(p"/") =>
      defaultActionBuilder {
        Results.Ok("success!")
      }
  })
  override lazy val configuration: Configuration =
    Configuration("foo" -> "bar", "ehcacheplugin" -> "disabled").withFallback(context.initialConfiguration)
}

上面
* 我们在实现中定义了导入,以防止在断言动词时sirdplay.api.http包之间发生冲突。
* 我们定义了一个测试路由器并实现了相应的路由,在本例中,我们匹配根补丁。
* 我们覆盖了配置以提供要在测试中使用的附加值,这当然可选。

§使用现有组件

如果我们想使用现有的应用程序组件,我们只需在测试中实例化它们。

override def components: BuiltInComponents = new SomeAppComponents(context)

此外,还可以覆盖组件中的任何定义,以提供额外的配置或模拟数据库等。

override def components: BuiltInComponents = new SomeAppComponents(context) {
  override lazy val configuration: Configuration =
    Configuration("ehcacheplugin" -> "enabled").withFallback(context.initialConfiguration)
}

§完整示例

class ExampleComponentsSpec extends PlaySpec with OneAppPerSuiteWithComponents {

  // #scalacomponentstest-inlinecomponents
  override def components: BuiltInComponents = new BuiltInComponentsFromContext(context) with NoHttpFiltersComponents {

    import play.api.mvc.Results
    import play.api.routing.Router
    import play.api.routing.sird._

    lazy val router: Router = Router.from({
      case GET(p"/") =>
        defaultActionBuilder {
          Results.Ok("success!")
        }
    })
    override lazy val configuration: Configuration =
      Configuration("foo" -> "bar", "ehcacheplugin" -> "disabled").withFallback(context.initialConfiguration)
  }
  // #scalacomponentstest-inlinecomponents

  "The OneAppPerSuiteWithComponents trait" must {
    "provide an Application" in {
      import play.api.test.Helpers.GET
      import play.api.test.Helpers.route
      val Some(result: Future[Result]) = route(app, FakeRequest(GET, "/"))
      Helpers.contentAsString(result) must be("success!")
    }
    "override the configuration" in {
      app.configuration.getOptional[String]("foo") mustBe Some("bar")
    }
  }
}

§嵌套规范

如果您有许多可以共享相同应用程序的测试,并且不想将它们全部放在一个测试类中,可以将它们放在不同的套件类中。这些将是您的嵌套套件。创建一个扩展适当特征的主套件,例如OneAppPerSuiteWithComponents,并声明嵌套套件。最后,使用@DoNotDiscover注释嵌套套件,并让它们扩展ConfiguredApp。以下是一个示例

class NestedExampleSpec
    extends Suites(new OneSpec, new TwoSpec, new RedSpec, new BlueSpec)
    with OneAppPerSuiteWithComponents
    with TestSuite {

  override def components: BuiltInComponents = new BuiltInComponentsFromContext(context) with NoHttpFiltersComponents {

    import play.api.mvc.Results
    import play.api.routing.Router
    import play.api.routing.sird._

    lazy val router: Router = Router.from({
      case GET(p"/") =>
        defaultActionBuilder {
          Results.Ok("success!")
        }
    })

    override lazy val configuration: Configuration =
      Configuration("ehcacheplugin" -> "disabled").withFallback(context.initialConfiguration)
  }
}

// These are the nested suites
@DoNotDiscover class OneSpec extends PlaySpec with ConfiguredApp {
  "OneSpec" must {
    "make the Application available implicitly" in {
      def getConfig(key: String)(implicit app: Application) = app.configuration.getOptional[String](key)

      getConfig("ehcacheplugin") mustBe Some("disabled")
    }
  }

}

@DoNotDiscover class TwoSpec extends PlaySpec with ConfiguredApp

@DoNotDiscover class RedSpec extends PlaySpec with ConfiguredApp

@DoNotDiscover class BlueSpec extends PlaySpec with ConfiguredApp {

  "The NestedExampleSpec" must {
    "provide an Application" in {
      import play.api.test.Helpers.GET
      import play.api.test.Helpers.route
      val Some(result: Future[Result]) = route(app, FakeRequest(GET, "/"))
      Helpers.contentAsString(result) must be("success!")
    }
  }
}

下一步: 使用数据库进行测试


发现文档中的错误?此页面的源代码可以在 这里 找到。阅读完 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?前往 我们的社区论坛 与社区开始对话。