§コンパイル時依存性注入によるテスト
アプリケーションを手動で接続している場合、またはコンパイル時依存性注入を使用している場合は、アプリケーションコンポーネントを直接使用およびカスタマイズしたり、テストケースに固有のテストバリアントを作成したりできます。フィルターの変更とオーバーライド、ルートの定義、設定の指定なども可能です。
§BuiltInComponentsFromContext
BuiltInComponentsFromContextは、コンポーネントを簡単にブートストラップするための簡単な方法を提供します。コンテキストが与えられると、必要な組み込みコンポーネント(environment
、configuration
、applicationLifecycle
など)がすべて提供されます。
コンパイル時依存性注入で説明されているように、これはアプリケーションを手動で接続する最も一般的な方法です。
テスト時には、完全な機能テストのために完全なアプリケーションを起動できる実際のコンポーネントを使用するか、必要に応じてアプリケーションのサブセットを起動するテストコンポーネントを作成できます。
§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)
}
上記
* 動詞をアサートする際にsird
パッケージとplay.api.http
パッケージ間の競合を防ぐために、実装内にインポートを定義します。
* テストルーターを定義し、適切なルートを実装します。この例では、ルートパッチに一致します。
* テスト内で使用される追加の値を提供するために設定をオーバーライドします。これはもちろんオプションです。
§既存のコンポーネントの使用
既存のアプリケーションコンポーネントを使用する場合は、テスト内でそれらをインスタンス化するだけです。
override def components: BuiltInComponents = new SomeAppComponents(context)
さらに、この段階でcomponents
内の定義をオーバーライドして、追加の設定を提供したり、たとえばデータベースをモックしたりすることもできます。
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")
}
}
}
§ネストされた仕様
同じApplication
を共有できるテストが多くあり、それらをすべて1つのテストクラスに配置したくない場合は、それらを異なるSuite
クラスに配置できます。これらがネストされたスイートになります。適切なトレイト
(たとえばOneAppPerSuiteWithComponents
)を拡張し、ネストされたSuite
を宣言するマスタースイートを作成します。最後に、ネストされたスイートに@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!")
}
}
}
次へ: データベースを使ったテスト
このドキュメントに誤りを見つけましたか?このページのソースコードはこちらにあります。ドキュメントガイドラインを読んだ後、プルリクエストを自由に貢献してください。質問やアドバイスを共有したいですか?コミュニティフォーラムにアクセスして、コミュニティとの会話を始めましょう。