Когда я тестирую свой php-код с помощью PHPUnit, я пытаюсь найти правильный способ имитировать объект без насмешки. любой из его методов.
Проблема в том, что если я не вызову getMockBuilder () -> setMethods ()
, то все методы объекта будут имитированы, и я не смогу вызвать метод, который хочу протестировать; но если я сделаю вызов setMethods ()
, то мне нужно будет указать, какой метод имитировать, но я не хочу вообще имитировать какие-либо методы. Но мне нужно создать макет, чтобы не вызывать конструктор в моем тесте.
Вот тривиальный пример метода, который я хотел бы протестировать:
class Foobar
{
public function __construct()
{
// stuff happens here ...
}
public function myMethod($s)
{
// I want to test this
return (strlen($s) > 3);
}
}
Я мог бы протестировать myMethod ()
с:
$obj = new Foobar();
$this->assertTrue($obj->myMethod('abcd'));
Но это вызовет конструктор Foobar, который мне не нужен . Вместо этого я бы попробовал:
$obj = $this->getMockBuilder('Foobar')->disableOriginalConstructor()->getMock();
$this->assertTrue($obj->myMethod('abcd'));
Но вызов getMockBuilder ()
без использования setMethods ()
приведет к тому, что все его методы будут издеваться и вернут null, поэтому мой вызов myMethod ()
вернет null, не касаясь кода, который я собираюсь проверить.
Мое обходное решение таково:
$obj = $this->getMockBuilder('Foobar')->setMethods(array('none'))
->disableOriginalConstructor()->getMock();
$this->assertTrue($obj->myMethod('abcd'));
Это имитирует метод с именем 'none', которого не существует, но PHPUnit не заботится. Он оставит myMethod () незащищенным, чтобы я мог его вызвать, а также позволит мне отключить конструктор, чтобы я не называл его.Идеально! За исключением того, что кажется обманом указывать имя метода, которого не существует - 'none', 'blargh' или 'xyzzy'.
Как правильно это сделать?