19

単体テストと 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);

と の 2 つのメソッドの戻り値をシミュレートする必要がありgetClass()ますgetName()。例えば:

$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));
4

3 に答える 3

19

ConfigurationInterface に「getClass」メソッドの宣言がないためです。このインターフェイスでの唯一の宣言は、メソッド「getAliasName」です。

必要なのは、スチューブするメソッドをモックに伝えることだけです。

$cls = 'Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface';
$mock = $this->getMock($cls, 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'));
于 2012-09-26T11:06:33.240 に答える
13

Cyprian の回答は役に立ちましたが、注意すべき点があります。存在しないクラスをモックすることができ、PHPUnit は文句を言いません。だからあなたはできる

$mock = $this->getMock('SomeClassThatDoesntExistOrIsMisspelledOrPerhapsYouForgotToRequire');

これは、ConfigurationInterface実行時にその時点で存在しない場合でも、次のようなメッセージが表示されることを意味します

致命的なエラー: 未定義のメソッド Mock_ConfigurationInterface_21e9dccf::getClass() を呼び出します。

メソッドがクラスに実際に存在することが確実な場合は、クラス自体が存在しないことが問題である可能性があります (メソッドを要求していないか、スペルを間違えているなどの理由で)。


OP はinterfaceを使用しています。getMockオーバーライドするメソッドのリストを指定せずに呼び出す必要があることに注意してください。そうしないと、 を渡すかarray()、すべてのメソッド名を渡す必要があります。そうしないと、次のようなエラーが発生します。

PHP 致命的なエラー: クラス Mock_HttpRequest_a7aa9ffd には 4 つの抽象メソッドが含まれているため、抽象として宣言するか、残りのメソッド (HttpRequest::setOption、HttpRequest::execute、HttpRequest::getInfo、...) を実装する必要があります。

于 2014-05-04T08:08:33.523 に答える
1

Tyler Collier の警告は公正ですが、それをどのようにコーディングするかについてのコード スニペットは含まれていません。これは非常に厄介であり、代わりにインターフェイスを修正する必要があることに注意してください。その警告が追加された場合:

$methods = array_map(function (\ReflectionMethod $m) { return $m->getName();}, (new \ReflectionClass($interface))->getMethods());
$methods[] = $missing_method;
$mock = $this->getMock($interface,  $methods);
于 2015-04-01T16:23:24.003 に答える