コントローラーのテスト
いくつかの新しいヘルパークラスとトレイトを使用することで、コントローラーのテストが容易になります。コントローラーのテストでは、アプリケーション全体のブートストラッププロセスを実行することなく、コントローラー内のコードを実行できます。フィーチャートールを使用する方が簡単な場合が多いですが、必要な場合はこの機能を使用できます。
注記
フレームワーク全体がブートストラップされていないため、この方法でコントローラーをテストできない場合があります。
ヘルパートレイト
コントローラーテストを有効にするには、テスト内でControllerTestTrait
トレイトを使用する必要があります。
<?php
namespace CodeIgniter;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\ControllerTestTrait;
use CodeIgniter\Test\DatabaseTestTrait;
class TestControllerA extends CIUnitTestCase
{
use ControllerTestTrait;
use DatabaseTestTrait;
}
トレイトを含めたら、リクエストとレスポンスクラス、リクエストボディ、URIなどを含む環境の設定を開始できます。controller()
メソッドを使用して使用するコントローラーを指定し、コントローラーの完全修飾クラス名をパラメーターとして渡します。最後に、実行するメソッドの名前をパラメーターとしてexecute()
メソッドを呼び出します。
<?php
namespace CodeIgniter;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\ControllerTestTrait;
use CodeIgniter\Test\DatabaseTestTrait;
class TestControllerA extends CIUnitTestCase
{
use ControllerTestTrait;
use DatabaseTestTrait;
public function testShowCategories()
{
$result = $this->withURI('http://example.com/categories')
->controller(\App\Controllers\ForumController::class)
->execute('showCategories');
$this->assertTrue($result->isOK());
}
}
ヘルパーメソッド
controller($class)
テストするコントローラーのクラス名を指定します。最初のパラメーターは、完全修飾クラス名(つまり、名前空間を含む)である必要があります。
<?php
$this->controller(\App\Controllers\ForumController::class);
execute(string $method, …$params)
コントローラー内で指定されたメソッドを実行します。最初のパラメーターは実行するメソッドの名前です。
<?php
$results = $this->controller(\App\Controllers\ForumController::class)
->execute('showCategories');
2番目以降のパラメーターを指定することで、コントローラーメソッドに渡すことができます。
これは、レスポンス自体を確認するための多くのルーチンを提供する新しいヘルパークラスを返します。詳細は下記を参照してください。
withConfig($config)
変更されたバージョンの **app/Config/App.php** を渡して、異なる設定でテストすることができます。
<?php
$config = new \Config\App();
$config->appTimezone = 'America/Chicago';
$results = $this->withConfig($config)
->controller(\App\Controllers\ForumController::class)
->execute('showCategories');
指定しない場合、アプリケーションのApp設定ファイルが使用されます。
withRequest($request)
テストのニーズに合わせて調整された **IncomingRequest** インスタンスを提供できます。
<?php
$request = new \CodeIgniter\HTTP\IncomingRequest(
new \Config\App(),
new \CodeIgniter\HTTP\URI('http://example.com'),
null,
new \CodeIgniter\HTTP\UserAgent()
);
$request->setLocale($locale);
$results = $this->withRequest($request)
->controller(\App\Controllers\ForumController::class)
->execute('showCategories');
指定しない場合、デフォルトのアプリケーション値を持つ新しいIncomingRequestインスタンスがコントローラーに渡されます。
withResponse($response)
**Response** インスタンスを提供できます。
<?php
$response = new \CodeIgniter\HTTP\Response(new \Config\App());
$results = $this->withResponse($response)
->controller(\App\Controllers\ForumController::class)
->execute('showCategories');
指定しない場合、デフォルトのアプリケーション値を持つ新しいResponseインスタンスがコントローラーに渡されます。
withLogger($logger)
**Logger** インスタンスを提供できます。
<?php
$logger = new \CodeIgniter\Log\Handlers\FileHandler();
$results = $this->withResponse($response)
->withLogger($logger)
->controller(\App\Controllers\ForumController::class)
->execute('showCategories');
指定しない場合、デフォルトの設定値を持つ新しいLoggerインスタンスがコントローラーに渡されます。
withURI(string $uri)
このコントローラーが実行されたときにクライアントがアクセスしていたURLをシミュレートする新しいURIを提供できます。これは、コントローラー内でURIセグメントを確認する必要がある場合に役立ちます。パラメーターは有効なURIを表す文字列のみです。
<?php
$results = $this->withURI('http://example.com/forums/categories')
->controller(\App\Controllers\ForumController::class)
->execute('showCategories');
予期せぬ事態を避けるために、テスト中に常にURIを提供することをお勧めします。
注記
v4.4.0以降、このメソッドはURIを持つ新しいRequestインスタンスを作成します。RequestインスタンスはURIインスタンスを持つ必要があります。Config\App
でURI文字列のホスト名が無効な場合、有効なホスト名が設定されます。
withBody($body)
リクエストにカスタムボディを提供できます。これは、JSON値をボディとして設定する必要があるAPIコントローラーをテストする場合に役立ちます。パラメーターはリクエストのボディを表す文字列のみです。
<?php
$body = json_encode(['foo' => 'bar']);
$results = $this->withBody($body)
->controller(\App\Controllers\ForumController::class)
->execute('showCategories');
レスポンスの確認
ControllerTestTrait::execute()
はTestResponse
のインスタンスを返します。レスポンステストで、このクラスを使用してテストケースで追加のアサーションと検証を実行する方法について説明します。
フィルターテスト
コントローラーテストと同様に、フレームワークはカスタムフィルターとプロジェクトでのルーティングでの使用をテストするのに役立つツールを提供します。
ヘルパートレイト
コントローラーテスターと同様に、これらの機能を有効にするには、テストケースにFilterTestTrait
を含める必要があります。
<?php
namespace CodeIgniter;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\FilterTestTrait;
class FilterTestCase extends CIUnitTestCase
{
use FilterTestTrait;
}
設定
コントローラーテストとの論理的な重複のため、FilterTestTrait
はControllerTestTrait
と連携して動作するように設計されています。両方を同じクラスで使用する必要がある場合、トレイトを含めるとCIUnitTestCase
はそのsetUp
メソッドを検出し、テストに必要なすべてのコンポーネントを準備します。特別な設定が必要な場合は、サポートメソッドを呼び出す前にプロパティを変更できます。
$request
デフォルトのIncomingRequest
サービスの用意されたバージョン$response
デフォルトのResponseInterface
サービスの用意されたバージョン$filtersConfig
デフォルトのConfig\Filters
設定(注:検出はFilters
によって処理されるため、モジュールエイリアスは含まれません)$filters
上記の3つのコンポーネントを使用したCodeIgniter\Filters\Filters
のインスタンス$collection
Config\Routes
の検出を含む、準備済みのRouteCollection
のバージョン
デフォルト設定は通常、本番プロジェクトを最も忠実にエミュレートするため、テストには最適ですが(例として)、フィルターがフィルターされていないルートで誤ってトリガーされる状況をシミュレートする場合は、設定に追加できます。
<?php
namespace CodeIgniter;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\FilterTestTrait;
final class FilterTestCase extends CIUnitTestCase
{
use FilterTestTrait;
protected function testFilterFailsOnAdminRoute()
{
$this->filtersConfig->globals['before'] = ['admin-only-filter'];
$this->assertHasFilters('unfiltered/route', 'before');
}
// ...
}
ルートの確認
最初のヘルパーメソッドはgetFiltersForRoute()
です。これは、指定されたルートをシミュレートし、コントローラーやルーティングコードを実行することなく、指定された位置(「before」または「after」)で実行されるすべてのフィルター(エイリアスによる)のリストを返します。これにより、コントローラーテストやHTTPテストと比較して、パフォーマンスが大幅に向上します。
- getFiltersForRoute($route, $position)
- パラメーター:
$route (
string
) – チェックするURI$position (
string
) – チェックするフィルターメソッド、「before」または「after」
- 戻り値:
実行される各フィルターのエイリアス
- 戻り値の型:
string[]
使用例
<?php $result = $this->getFiltersForRoute('/', 'after'); // ['toolbar']
フィルターメソッドの呼び出し
設定で説明されているプロパティはすべて、他のテストからの干渉や妨害なしに、最大限のパフォーマンスを確保するために設定されています。次のヘルパーメソッドは、これらのプロパティを使用してフィルターコードを安全にテストし、結果を確認するための呼び出し可能なメソッドを返します。
- getFilterCaller($filter, $position)
- パラメーター:
$filter (
FilterInterface|string
) – フィルターインスタンス、クラス、またはエイリアス$position (
string
) – 実行するフィルターメソッド、「before」または「after」
- 戻り値:
シミュレートされたフィルターイベントを実行するための呼び出し可能なメソッド
- 戻り値の型:
Closure
使用例
<?php namespace CodeIgniter; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\FilterTestTrait; final class FilterTestCase extends CIUnitTestCase { use FilterTestTrait; protected function testUnauthorizedAccessRedirects() { $caller = $this->getFilterCaller('permission', 'before'); $result = $caller('MayEditWidgets'); $this->assertInstanceOf('CodeIgniter\HTTP\RedirectResponse', $result); } }
Closure
は、フィルターメソッドに渡される入力パラメーターを取ることができることに注意してください。
アサーション
上記のヘルパーメソッドに加えて、FilterTestTrait
には、テストメソッドを簡素化するいくつかのアサーションも含まれています。
assertFilter()
assertFilter()
メソッドは、指定された位置にある指定されたルートが(エイリアスによる)フィルターを使用していることを確認します。
<?php
// Make sure users are logged in before checking their account
$this->assertFilter('users/account', 'before', 'login');
assertNotFilter()
assertNotFilter()
メソッドは、指定された位置にある指定されたルートが(エイリアスによる)フィルターを使用していないことを確認します。
<?php
// Make sure API calls do not try to use the Debug Toolbar
$this->assertNotFilter('api/v1/widgets', 'after', 'toolbar');
assertHasFilters()
assertHasFilters()
メソッドは、指定された位置にある指定されたルートに少なくとも1つのフィルターが設定されていることを確認します。
<?php
// Make sure that filters are enabled
$this->assertHasFilters('filtered/route', 'after');
assertNotHasFilters()
assertNotHasFilters()
メソッドは、指定された位置にある指定されたルートにフィルターが設定されていないことを確認します。
<?php
// Make sure no filters run for our static pages
$this->assertNotHasFilters('about/contact', 'before');