web-dev-qa-db-ja.com

保護されたプロパティとメソッドをモックすることは可能ですか?

PHP Mockeryで保護されたプロパティをモックすることは可能ですか?

同じクラスの保護されたプロパティから取得された配列に対して何らかの魔法を実行するメソッドを持つクラスを取得しました。これを「a」と呼びます。

その保護されたプロパティは、同じクラスの別のメソッドbによって埋められます。

保護されたプロパティをモックしてメソッドaをテストしたいので、最初にメソッドbをクラス分けする必要はありません。

それで、これは可能ですか?そうでない場合は、コードをリファクタリングする必要がありますか?または、他の方法があります(ベストプラクティスを考慮)。

15
Ilyes512

保護されたメソッドをモックすることは可能ですが、一部の人々が指摘しているように、これらのメソッドをモックする必要があると感じた場合は、コードをリファクタリングすることをお勧めします。

保護されたメソッドをモックしたい場合は、以下の例に従ってこれを行うことができます。

$myMock = Mockery::mock('myClass')->shouldAllowMockingProtectedMethods();

このモックを使用すると、パブリックメソッドをモックするのと同じ方法で保護されたメソッドをモックすることができます。

17
Fredrik Salin

コードに問題がなく、テストを容易にするためにコードを変更する理由がないと思う場合があります(これは私の意見では正当な理由です)。私が行うことは、オブジェクト内でリフレクションを使用することです。このようなヘルパーメソッドを使用することもできます。 :

class MockingHelpers
{
    public static function mockProperty($object, string $propertyName, $value)
    {
        $reflectionClass = new \ReflectionClass($object);

        $property = $reflectionClass->getProperty($propertyName);
        $property->setAccessible(true);
        $property->setValue($object, $value);
        $property->setAccessible(false);
    }
}

アクセシブルはリフレクションコンテキストでのみ適用されるため、損傷は発生しないことに注意してください。

これは完璧な解決策ではありません。コードに実際に問題がある場合もありますが、これは役立つ可能性があります。

4
Renato Mefi