90

phpunitがモックオブジェクトのコンストラクターを呼び出さなくて済むようにする方法は何ですか?それ以外の場合は、コンストラクター引数としてモックオブジェクト、そのための別のオブジェクトなどが必要になります。APIは次のようになります。

getMock($className, $methods = array(), array $arguments = array(),
        $mockClassName = '', $callOriginalConstructor = TRUE,
        $callOriginalClone = TRUE, $callAutoload = TRUE)

動作しません。$callOriginalConstructorfalseに設定されていても、コンストラクター引数について不平を言います。

コンストラクターにはオブジェクトが1つしかなく、それは依存性注入です。ですから、そこにはデザイン上の問題はないと思います。

4

7 に答える 7

148

getMockBuilder代わりに使用できますgetMock

$mock = $this->getMockBuilder('class_name')
    ->disableOriginalConstructor()
    ->getMock();

詳細については、PHPUnitのドキュメントの「テストダブル」のセクションを参照してください。

これは可能ですが、必要がない方がはるかに優れています。コードをリファクタリングできるので、(コンストラクターを使用して)具体的なクラスを挿入する必要はなく、インターフェースのみに依存します。これは、コンストラクターの動作を変更するようにPHPUnitに指示しなくても、インターフェースをモックまたはスタブできることを意味します。

于 2011-06-08T10:11:39.187 に答える
42

どうぞ:

    // Get a Mock Soap Client object to work with.
    $classToMock = 'SoapClient';
    $methodsToMock = array('__getFunctions');
    $mockConstructorParams = array('fake wsdl url', array());
    $mockClassName = 'MyMockSoapClient';
    $callMockConstructor = false;
    $mockSoapClient = $this->getMock($classToMock,
                                     $methodsToMock,
                                     $mockConstructorParams,
                                     $mockClassName,
                                     $callMockConstructor);
于 2009-03-09T22:38:29.930 に答える
4

補遺として、expects()モックしたオブジェクトに呼び出しをアタッチしてから、コンストラクターを呼び出したいと思いました。PHPUnit 3.7.14 では、呼び出したときに返されるdisableOriginalConstructor()オブジェクトは文字通りオブジェクトです。

// Use a trick to create a new object of a class
// without invoking its constructor.
$object = unserialize(
sprintf('O:%d:"%s":0:{}', strlen($className), $className)

残念ながら、PHP 5.4 には、使用されていない新しいオプションがあります。

ReflectionClass::newInstanceWithoutConstructor

これは利用できなかったため、手動でクラスを反映してからコンストラクターを呼び出す必要がありました。

$mock = $this->getMockBuilder('class_name')
    ->disableOriginalConstructor()
    ->getMock();

$mock->expect($this->once())
    ->method('functionCallFromConstructor')
    ->with($this->equalTo('someValue'));

$reflectedClass = new ReflectionClass('class_name');
$constructor = $reflectedClass->getConstructor();
$constructor->invoke($mock);

functionCallFromConstructisの場合、保護されたメソッドがモックされるようprotectedに具体的に使用する必要があることに注意してください。setMethods()例:

    $mock->setMethods(array('functionCallFromConstructor'));

setMethods()コールの前にコールする必要がありexpect()ます。個人的には、これを after disableOriginalConstructor()but beforeにチェーンしgetMock()ます。

于 2013-03-08T02:21:53.233 に答える
1

おそらく、コンストラクターの引数として渡すスタブを作成する必要があります。次に、モック オブジェクトの連鎖を断ち切ることができます。

于 2008-12-01T22:30:16.410 に答える
0

PHPUnit は、モック化されたオブジェクトでコンストラクターを呼び出すように設計されています。これを防ぐには、次のいずれかを行う必要があります。

  1. モック オブジェクトを依存関係として、モックに問題があるオブジェクトに挿入します。
  2. 親コンストラクターを呼び出さない、呼び出そうとしているクラスを拡張するテスト クラスを作成します。
于 2008-12-08T21:08:18.367 に答える