web-dev-qa-db-ja.com

機能テストでSymfony 2サービスをモックする方法は?

一部のメソッドではredis接続を使用しますが、すべてのメソッドでは使用しないsymfonyサービスがあります。

class ServiceA
{
    private $redis;

    public function __construct($redis)
    {
        $this->redis = $redis;
    }

    public function getRequest($param1, $param2)
    {
    $result = $param1+ $param2;
        return $request;
    }

    .. other methods which use $redis connection
}

GetRequestメソッドのみを使用するコードの機能テストを記述しています(このメソッドはredis接続を必要としません)が、コンストラクターが引数として接続を受け取るため、テストを実行するとredisサーバーに接続しようとしました。

Redis接続をまったく使用せず、元のコンストラクタを無視する模擬サービスを作成するにはどうすればよいですか?.

私は下記のアプローチを試みていますが、成功していません。私は元のコンストラクタを無効にしていますが、それでもredisを接続しようとします。

http://blog.lyrixx.info/2013/04/12/symfony2-how-to-mock-services-during-functional-tests.html

$serviceA = $this->getMockBuilder('ServiceA')
    ->disableOriginalConstructor()
    ->getMock();

static::$kernel->getContainer()->set('my_bundle.service.a', $serviceA);
28
vishal

ServiceAモックを作成したら、それをクライアントのコンテナに渡す必要があります(クライアントオブジェクトは独自のカーネルを構築するため、カーネルのコンテナではありません)。これを試して:

$client = self::createClient();

$serviceA = $this->getMockBuilder('ServiceA')
    ->disableOriginalConstructor()
    ->getMock();

$client->getContainer()->set('my_bundle.service.a', $serviceA);

リクエストを行うたびに、この模擬サービスを注入する必要があることに注意してください。これは、クライアントが2つの要求の間にカーネルを再構築するためです。

59
Cyprian

テストしたクラスをモックするのではなく、Redisクラスをモックしてインジェクトする必要があります。

このテストにRedisが使用されていない場合、モックを設定する必要さえありません。

$redis = $this->getMockBuilder('Redis')->disableOriginalConstructor()->getMock();
$serviceA = new ServiceA($redis);
5
Sven

モックされたサービスを処理する特別なツールがあります- https://github.com/ramunasd/symfony-container-mocks

そのように簡単です:

$service = static::$kernel->getContainer()->prophesize('my.custom.service');
4
Ramunas Dronga

やってみました ?

$serviceA = $this->getMock('ServiceA', array('getRequest'), array(), '', false);
0
adam187