DI コンテナからサービスをフェッチすることは、私のテスト スイートのスモーク テストの不可欠な部分です。次のテストでは、たとえば、コンテナーに登録されているサービスの構築に問題がないこと、およびこれらのサービスの構築に時間がかかりすぎないことを確認します。
private const DEFAULT_TRESHOLD = 30;
public function testServicesLoadInTime()
{
$client = static::createClient();
/**
* Add serviceid as key, possible values:
* - false: Skip test for this service
* - integer value: Custom responsetime
*/
$customCriteria = [
// See: https://github.com/symfony/monolog-bundle/issues/192
'monolog.activation_strategy.not_found' => false,
'monolog.handler.fingers_crossed.error_level_activation_strategy' => false,
// Should not be used directly (Factories will inject other parameters)
'liip_imagine.binary.loader.prototype.filesystem' => false,
// Services that are allowed to load longer (Only for CLI tasks like workers)
'assetic.asset_manager' => 1000,
];
foreach ($client->getContainer()->getServiceIds() as $id) {
if (isset($customCriteria[$id]) && $customCriteria[$id] === false) {
continue;
}
try {
$startedAt = microtime(true);
$service = $client->getContainer()->get($id);
$elapsed = (microtime(true) - $startedAt) * 1000;
$this->assertNotNull($service);
$treshold = $customCriteria[$id] ?? self::DEFAULT_TRESHOLD;
$this->assertLessThan($treshold, $elapsed, sprintf(
'Service %s loaded in %d ms which is more than the %d ms threshold',
$id, $elapsed, $treshold
));
} catch (InactiveScopeException $e) {
// Noop
} catch (\Throwable $ex) {
$this->fail(sprintf("Fetching service %s failed: %s", $id, $ex->getMessage()));
}
}
}
でも。Symfony のバージョン 4では、デフォルトでサービスがプライベートになります。今後のバージョン 3.4 ではget()
、サービスがパブリックとしてマークされていない場合に、メソッドを使用してサービス コンテナからサービスをフェッチすると、非推奨の警告がトリガーされます。
これにより、すべてのサービスをコンストラクターの引数として受け取るパブリック サービスを作成せずに、このスモーク テストを実行し続ける方法があるかどうか疑問に思いました。これは、コンテナー内のほぼ 1000 のサービスが実行可能なオプションではありません。