コントローラーからElastic searchを呼び出して検索結果を返すカスタムモジュールに取り組んでいます。結果が正しく表示されることを確認するためだけに、単純なFunctional Php Unitテストを記述しようとしています。
以下は、私の機能的なphpユニットテストコードの簡略版です。
public function testSearchResulsShowUp() {
$account = $this->drupalCreateUser(['access content']);
$this->drupalLogin($account);
$this->drupalGet('/search/term1');
$this->assertResponse(200);
$this->assertText('Term 1');
}
これが私のコントローラーの簡易バージョンです:
/**
* Search controller.
*/
class SearchController extends ControllerBase {
public function getContent(search) {
$client = Client::getClient();
// Client connects to Elastic search and then returns
// a result.
...
...
// Will return Term 1
}
}
これが私のクライアントクラスの簡略化されたバージョンです:
/**
* Class Client.
*/
class Client {
/**
* Get client.
*/
public static function getClient() {
$cluster_id = \Drupal::state()->get('elasticsearch_connector_get_default_connector');
$elasticsearchCluster = \Drupal::entityManager()->getStorage('elasticsearch_cluster')->load($cluster_id);
$clientManager = \Drupal::service('elasticsearch_connector.client_manager');
$client = $clientManager->getClientForCluster($elasticsearchCluster);
return $client;
}
}
GetClientメソッドをどうにかしてモックできるようにしたいので、コントローラまたはそれ以降のどこかで呼び出されると、元のメソッドの代わりにモックが呼び出されます。これが本当の単体テストであった場合、私たちはそれを実行できることを知っていますが、これは機能テストなので、どのように行うかわかりません。
テストが作成しているリクエストは完全に新しいPHPプロセスを起動してそのリクエストのコンテンツを配信するため、テストの実行中にメモリ内で行った処理は何も新しいHTTPに反映されません。リクエストプロセス。
幸い、単一のリクエストよりも長い機能テスト内でcanを使用できるHTTPクライアントを作成するためのいくつかのテクニックがあります。この手法では、モジュールが有効になっている間に発生するすべてのリクエストに対して、コンテナ内のHTTPクライアントを置き換えるテストモジュールを作成します。
あなたのテストはそれから:
このようなテストモジュールの主要な部分は次のとおりです。
my_module/tests/modules/my_module_http_client/services.yml
services:
my_module_http_client.http_client:
decorates: 'http_client'
class: 'Drupal\my_module_http_client\MockHttpClient'
my_module/tests/modules/my_module_http_client/src/TestHttpClient
<?php
namespace Drupal\my_module_http_client;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Response;
/**
* Test HTTP client for the air quality test.
*/
class TestHttpClient extends Client {
/**
* {@inheritdoc}
*/
public function get($uri, array $options = []) {
return new Response(200, ['type' => 'text/xml'], file_get_contents(__DIR__ . '/some-test-fixture.xml'));
}
}
もちろん::get
の本体では、好きなロジックをプログラムできます。一般的なパターンは、状態APIを使用して、テストでクライアントの動作を指定できるようにすることです。たとえば、どの応答フィクスチャを返すかを設定するようなものです。
この種の機能テストは、システム全体がエンドツーエンドで機能していることを確認するのに非常に役立ちます。ただし、これを警告します。分離してテストできるコントローラー内のユニットを識別することも重要です。単体テストでは、完全にブートストラップされた実装よりもはるかに高速で、多くのシナリオをテストできることがよくあります。