注意点
PHPでのモックオブジェクトには、制限と注意点があります。いくつかの機能はモックできないか、もしくは いまのところ(!) モックできません。そうした状況に出会ったら、ドキュメント化するか、可能であれば解決できるように、どうか、どうか、GitHubでissueを作成してください。注意点のリストは以下の通りです。
- Publicの
__wakeup()
メソッドを含むクラスはモックできますが、モックした__wakeup()
メソッドは何も動作せず、エクスペクションを指定することもできません。これはMockeryが__construct()
の愚行を無視するため、オブジェクトをシリアライズ/非シリアライズする必要があり、__wakeup()
メソッドをモックしようと試みると、通常はBadMethodCallException
が投げられる事態を引き起こすからです。 - たとえば、
__call()
メソッドを起動するような、本物ではないメソッドを使用しているクラスは、最低1つのエクスペクションが定義されない限り、例外を投げます。(シンプルにshouldReceive()
呼び出すだけで、十分です。)なぜなら、Mockeryにはそのメソッド名を認識する手段がないためです。 - Mockeryは本当のクラスを置き換える、2つのシナリオを持っています。インスタンスモックとエイリアスモックです。通常require文かinclude文により実クラスがロードされますが、実クラスがロード済みの場合、両方のシナリオともPHPのfatalエラーを発生させます。これら2つのモックタイプは、オートローディングが使用されており、
require()
やrequire_once()
などを使用した、ファイルベースによる明示的なクラスロードが行われない場合に使用します。 - 内部PHPクラスは、
Reflection
を使用して完全に分析されません。たとえば、Reflection
はこうした内部クラスのメソッドに対し期待されている引数の詳細を明確にできません。その結果、参照による値を受け取るように定義されているメソッドパラーターで問題が起きます。(Mockeryはこうした状態を認知できませんし、値がスカラーか配列で渡されると仮定しています。)内部クラスのメソッド引数の参照が必要であれば、\Mockery\Configuration::setInternalClassMethodParamMap()
メソッドを使用してください。 - 実装するインターフェイス名で、大文字小文字を間違えたモックを生成し、次に同じインターフェイスを今度は間違えずに実装したモックを生成すると、PHPの
class_exists
と関連するファンクションが大文字小文字を識別しないため、動作が定まりません。こうした間違いを防ぐためには、PHPの::class
キーワードを使用してください。
上記の注意点は、PHPのアーキテクチャによるもので、避けがたいと考えられます。ですが皆さんが、もし解決策(もしくは既存の方法より良いやり方)を見つけ出したら、教えてください。