私はユニットテストとPHPUnitに不慣れです。
ConfigurationInterface
インターフェースを実装する完全な制御が可能なモックが必要です。テスト対象はReportEventParamConverter
オブジェクトであり、テストではオブジェクトとインターフェイス間の相互作用を確認する必要があります。
ReportEventParamConverter
オブジェクト(ここでは簡略化):
_class ReportEventParamConverter implements ParamConverterInterface
{
/**
* @param Request $request
* @param ConfigurationInterface $configuration
*/
function apply(Request $request, ConfigurationInterface $configuration)
{
$request->attributes->set($configuration->getName(), $reportEvent);
}
/**
* @param ConfigurationInterface $configuration
* @return bool
*/
function supports(ConfigurationInterface $configuration)
{
return 'My\Namespaced\Class' === $configuration->getClass();
}
}
_
そして、これは私がインターフェースをモックしようとしている方法です:
_$cls = 'Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface';
$mock = $this->getMock($mockCls);
_
getClass()
とgetName()
の2つのメソッドの戻り値をシミュレートする必要があります。例えば:
_$mock->expects($this->any())
->method('getClass')
->will($this->returnValue('Some\Other\Class'))
;
_
新しいReportEventParamConverter
メソッドを作成してsupports()
メソッドをテストすると、次のPHPUnitエラーが発生します。
致命的なエラー:未定義のメソッドMock_ConfigurationInterface_21e9dccf :: getClass()を呼び出します。
_$converter = new ReportEventParamConverter();
$this->assertFalse($converter->supports($mock));
_
これは、ConfigurationInterfaceに「getClass」メソッドの宣言がないためです。このインターフェースでの唯一の宣言は、メソッド「getAliasName」です。
必要なのは、スタブするメソッドをモックに伝えることだけです。
$cls = 'Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface';
$mock = $this->getMock($mockCls, array('getClass', 'getAliasName'));
「getClass」宣言はありませんが、存在しないメソッドをスタブ/モックすることもできます。そのため、あなたはそれをあざけることができます:
$mock->expects($this->any())
->method('getClass')
->will($this->returnValue('Some\Other\Class'));
ただし、それに加えて、インターフェイスのメソッドまたは抽象メソッドであり、「実装」する必要がある限り、「getAliasName」メソッドをモックする必要があります。例えば。:
$mock->expects($this->any())
->method('getAliasName')
->will($this->returnValue('SomeValue'));
キプリアンの答えは私を助けましたが、注意すべき落とし穴があります。存在しないクラスをモックすることができ、PHPUnitは文句を言いません。だからあなたはすることができます
_$mock = $this->getMock('SomeClassThatDoesntExistOrIsMisspelledOrPerhapsYouForgotToRequire');
_
つまり、実行時のその時点でConfigurationInterface
が存在しない場合でも、次のようなメッセージが表示されます。
致命的なエラー:未定義のメソッドMock_ConfigurationInterface_21e9dccf :: getClass()を呼び出します。
メソッドが実際にクラスに存在することが確実な場合、問題として考えられるのは、クラス自体が存在しないことです(必要がない、またはスペルを間違えたなどの理由で)
OPはインターフェースを使用しています。オーバーライドするメソッドのリストを指定せずにgetMock
を呼び出す必要があることに注意してください。呼び出す場合は、array()
を渡すか、すべてのメソッド名を渡す必要があります。そうしないと、次のようになります。次のようなエラー:
PHPの致命的なエラー:クラスMock_HttpRequest_a7aa9ffdには4つの抽象メソッドが含まれているため、抽象として宣言するか、残りのメソッドを実装する必要があります(HttpRequest :: setOption、HttpRequest :: execute、HttpRequest :: getInfo、...)
Tyler Collierの警告は公正ですが、その周りのコーディング方法に関するコードスニペットは含まれていません。これは非常に厄介であり、代わりにインターフェイスを修正する必要があることに注意してください。その警告が追加されました:
$methods = array_map(function (\ReflectionMethod $m) { return $m->getName();}, (new \ReflectionClass($interface))->getMethods());
$methods[] = $missing_method;
$mock = $this->getMock($interface, $methods);