Когда я тестирую свой 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".
Каким будет правильный способ сделать это?