PHPUnit: методы stub undefined

Я должен что-то упустить. Я пытаюсь использовать методы stub в классе в PHPUnit, но когда я вызываю метод на объект mock, он сообщает мне, что метод не определен.

Пример класса для заглушки:

namespace MyApp; class MyStubClass { public function mrMethod() { // doing stuff } } 

Чтобы его заглушить, я пишу:

 // specifying all getMock() args to disable calling of class __construct() $stub = $this->getMock('MyStubClass', array(), array(), 'MockMyStubClass', false, false, false); $stub->expects($this->any()) ->method('mrMethod') ->will($this->returnValue('doing stuff')); 

Но при вызове метода stubbed я получаю исключение:

 $stub->mrMethod(); //PHP Fatal error: Call to undefined method MockMyStubClass::mrMethod() 

Я использую PHPUnit 3.4.3 с PHP 5.3.0.

Еще одна небольшая вещь, которую я заметил, заключалась в том, что если указание пространства имен в getMock() приводит к исключению загрузки класса из-за двойного пространства имен:

 $stub = $this->getMock('MyApp\MyStubClass'); // Fatal error: Class 'MyApp\MyApp\MyStubClass' not found 

Это поражает меня как довольно странное (и getmock () не будет принимать пространство имен с ведущей обратной косой чертой). Единственное, что я мог подумать, что это может быть связано с тем, что этот класс зарегистрирован на автозагрузчике?

Есть предположения?

Отвечая на мой вопрос:

Немного разочаровавшись, мне удалось все наладить. Я точно не знаю, в чем проблема, но обнаружил несколько вещей, которые могли бы помочь другим:

  • Убедитесь, что вы используете последнюю версию PHPUnit (3.4.6 на момент написания этой статьи)
  • Используйте полностью квалифицированное пространство имен минус первая обратная косая черта.

     $this->getMock('MyApp\Widgets\WidgetFactory'); 

Часть моей проблемы заключалась в том, что PHPUnit создавал класс-заглушку класса WidgetFactory который на самом деле не перекрывал MyApp\Widgets\WidgetFactory . Можно было бы ожидать, что возникнет исключение, если вы попытаетесь заглушить несуществующий класс, но это не похоже на путаницу пространства имен.

Кроме того, здесь возникает вопрос, который предполагает использование метода псевдонимов класса следующим образом:

  class_alias('MyApp\Widgets\WidgetFactory', 'WidgetFactory'); $this->getMock('WidgetFactory'); 

Хотя это временно решило мою проблему, я бы настоятельно советовал не использовать ее. class_alias() нельзя вызывать дважды для одного и того же псевдонима, не class_alias() исключения, что вызывает очевидную проблему, если используется в методе setup() или как часть генерации заглушки.

У меня была аналогичная проблема, моя проблема заключалась в том, что путь, который я писал, был чем-то вроде MyApp\Widgets\WidgetFactory\MyStubClass тогда как класс был примерно таким:

 namespace MyApp; class MyStubclass { public function mrMethod() { // doing stuff } } 

Таким образом, не было прописной буквы C в названии класса на пути