私の単体テストをうまく動作させるには問題があります。工場で作成されたサービスを使用するコントローラをテストしています。私が達成したいのは、アクティブなデータベース接続を使用せずにテストを実行できるように、工場を模擬サービスに置き換えることです。私のサービスマネージャの設定ファイルでオブジェクト・モッキング - 工場をサービス・マネージャーのサービスに置き換えるにはどうすればいいですか?
セットアップ
私は工場を指します。 工場では、ユニットテスト中に使用したくないアクティブなデータベース接続が必要です。
Namespace MyModule;
return [
'factories' => [
MyService::class => Factory\Service\MyServiceFactory::class,
],
];
注:私は、説明のためにクラス名と単純化された構成を変更しました。
このサービスでは、状況に関連しないため、私が今は行っていないマッパーを使用しています。マッパーは、独自のテストケースでテストされます。サービス自体にはそれ自身のテストケースもありますが、コントローラのアクションが動作するためには存在する必要があります。
コントローラアクションは、単にサービスから情報を受信します。
Namespace MyModule\Controller;
use MyModule\Service\MyService;
use Zend\Mvc\Controller\AbstractActionController;
class MyController extends AbstractActionController
{
/**
* @var MyService
*/
private $service;
/**
* @param MyService $service
*/
public function __construct(MyService $service)
{
$this->service = $service;
}
/**
* Provides information to the user
*/
public function infoAction()
{
return [
'result' => $this->service->findAll(),
];
}
}
注:再び、私は、クラス名を変更し、説明のための例を簡略化しています。私はこのような目的の工場を上書きしようとした私は私のテストケースでは
を試してみた
:
/**
* @return \Prophecy\Prophecy\ObjectProphecy|MyService
*/
private function mockService()
{
$service = $this->prophesize(MyService::class);
$service->findAll()->willReturn(['foo', 'bar']);
return $service;
}
/**
* @param \Zend\ServiceManager\ServiceManager $services
*/
private function configureServiceManager(ServiceManager $services)
{
$services->setAllowOverride(true);
$services->setService(MyService::class, $this->mockService()->reveal());
$services->setAllowOverride(false);
}
一見これは偉大に見えますが、それは動作しません。ファクトリをサービスマネージャのサービスリストに追加するだけで、ファクトリをオーバーライドしないようです。
$services->setService
から$services->setFactory
に変更すると、別の工場を建設する必要があります。私ができることは、モックマッパーをサービスに挿入するファクトリを作成することですが、それは間違っていると感じます。私はサービスやマッパーではなく、コントローラをテストしています。そのような複雑なソリューションを避けようとしているので、テストケースを簡単かつ明確に保ちます。
私の状況に関するオプションはありますか?サービスマネージャーのサービスでファクトリをオーバーライドすることは可能ですか、それとも間違っているのですか?
私は「別の工場を建設する」ことはできません。私は明らかにそれのクロージャを書くことができるので、これは必要ではありません。 –