単体テストについて頭を悩ませようとしていますが、見つけなければならないジグソーパズルがもう 1 つあります。
私がやろうとしているのは、次のコードのテストを書くことです。この場合、非常に単純なフロント コントローラー (PHP で記述) を用意しました。
class frontController
{
public function routeRequest($oRequest)
{
$sClassname = $oRequest->getController();
$sMethod = $oRequest->getAction();
$oController = new $sClassname();
$oResponse = $oController->{$sMethod}($oRequest);
return $oResponse;
}
}
私が抱えている問題は、コードが新しいオブジェクトを作成するためです。テスト ケース内で実際に何を行うかを厳密に制御できるように、リクエスト オブジェクトを簡単にモックできます。実際にコントローラーをテストダブルに置き換える最善の方法がわかりません。
IBM のこの記事では、コントローラーを作成するためのファクトリー メソッドを用意し、テストに使用する特定のクラスでこれをオーバーライドすることを提案しています。
class frontController
{
public function routeRequest($oRequest)
{
$sMethod = $oRequest->getAction();
$oController = $this->createController($oRequest);
$oResponse = $oController->{$sMethod}($oRequest);
return $oResponse;
}
protected function createController($oRequest)
{
$sClassname = $oRequest->getController();
return new $sClassname();
}
}
そして、おそらく次のようなテストのために:
class testFrontController extends frontController
{
public function setMockController($oMockController)
{
$this->oMc = $oMockController;
}
protected function createController($oRequest)
{
return $this->oMockController;
}
}
(これは記事が言っていることとはまったく異なりますが、これができれば私にとって最も役立つと思います)
別の解決策は、コントローラーを作成する別のクラスを持つことです。これは、frontController の依存クラスになります。このようにして、テスト中に factory/creation クラスを test double に置き換えることができます。このようなもの:
class frontController
{
public function routeRequest($oRequest, $oControllerFactory)
{
$sMethod = $oRequest->getAction();
$oController = $oControllerFactory->create($oRequest);
$oResponse = $oController->{$sMethod}($oRequest);
return $oResponse;
}
}
class controllerFactory
{
public function create($oRequest)
{
$sClassname = $oRequest->getController();
return new $sClassname();
}
}
依存性注入は、実際の「ルート」メソッドへのパラメーターではなく、フロントコントローラーコンストラクターまたはセッターを介して処理できると思います。
私はオプション2を好むと思います。
これらの 2 つの方法のどちらかが、この種のものをテストするための正しい方法ですか?
(おそらく、ここでは「良い方法」の方が適切です!)
オプション 1 とオプション 2 についての考えや提案、または実際に代替案を歓迎します。覚えておいてください-重要なことは、実行の一部として他のオブジェクトを作成するオブジェクトをテストする方法です。
ありがとう!