Я получаю доступ к PHPUnit и до сих пор нашел его довольно простым в использовании, но я столкнулся с тестовым примером, который вызывает у меня трудности.PHPUnit: Stubbing multiple interfaces
Я пишу код против набора интерфейсов, которые, как предполагается, будут реализовывать объекты (некоторые из них, некоторые самодельные), а для SUT требуется входной объект для реализации нескольких интерфейсов. Например:
class MyClass implements ArrayAccess, MyInterface
{
// ...
}
тестируемые делают вещи, такие как это:
class ClassToBeTested
{
protected $obj = NULL;
public function __construct ($obj)
{
$this -> obj = $obj;
}
public function methodToBeTested()
{
if ($this -> obj instanceof ArrayAccess)
&& ($this -> obj instanceof MyInterface)
{
// ...
}
}
public function otherMethodUnderTest()
{
if ($this -> obj instanceof ArrayAccess)
{
// ...
}
else
if ($this -> obj instanceof MyInterface)
{
// ...
}
}
}
я могу создать заглушку из одного интерфейса или других, но я не знаю, если вы можете создать огрызок, который реализует их оба.
protected function setUp()
{
$stubField = $this -> getMockBuilder ('ArrayAccess')
-> getMock();
$this -> object = new ClassToBeTested ($stubField);
}
или
protected function setUp()
{
$stubField = $this -> getMockBuilder ('MyInterface')
-> getMock();
$this -> object = new ClassToBeTested ($stubField);
}
Можно ли генерировать окурки из списка интерфейсов, или у меня есть незавершенная конкретный класс, который реализует ожидаемые интерфейсы? Это само по себе вызывает трудности, потому что классу, который нужно окутать, нужен другой объект, который должен быть передан его конструктору, и я не могу заставить disableOriginalConstructor() или setConstructorArgs() работать, я думаю, это потому, что конкретные классы, о которых идет речь, не реализуют сам конструктор, а наследуют его от суперкласса. Я пропустил что-то очевидное здесь?
+1 Потому что это такая кровавая очевидная идея, о которой я должен был подумать. Тем не менее я собираюсь оставить его открытым немного дольше, прежде чем принимать, чтобы посмотреть, что другие предлагают. – GordonM
Персоналии предпочитают @Maksim Kotlyar ответить как введение интерфейса в вашу прикладную кодовую базу в качестве заглушки для вашего теста, будет бесполезно менять ваш производственный код. –
@YohanG. В его нынешнем виде, возможно, да. Глядя на это снова (спустя более 4,5 лет!), Я думаю, что проблема, которую имеет ОП, на самом деле является симптомом более глубокой проблемы. $ Obj, который он передаёт CUT, может либо реализовать ArrayAccess, либо MyInterface. Мне кажется, что есть другая концепция, пытающаяся выйти. То, что он должен делать, - это захват одного интерфейса/класса в его CUT и позволяющий абстрагировать разницу между ними. Таким образом, избавиться от этих ужасных, если ... instanceof блоков и быть более полиморфными. – liquorvicar