В PHPUnit, как я макет родительских методов?

Я хочу протестировать метод класса, который вызывает родительский метод с тем же именем. Есть ли способ сделать это?

class Parent { function foo() { echo 'bar'; } } class Child { function foo() { $foo = parent::foo(); return $foo; } } class ChildTest extend PHPUnit_TestCase { function testFoo() { $mock = $this->getMock('Child', array('foo')); //how do i mock parent methods and simulate responses? } } 

Вы не издеваетесь и не заглушаете методы в тесте-тестировании (SUT). Если вы чувствуете, что вам нужно высмеять или заглушить метод в родительском элементе SUT, это, скорее всего, означает, что вы не должны использовать наследование, а агрегацию.

Вы издеваетесь над зависимостями субъекта-теста. Это означает, что любые другие объекты, которые SUT требует выполнения работы.

Подход, который работает для меня, – это реализация обертывания родительского вызова дочернего класса и, наконец, имитация этих оберток.

Вы изменили код:

 class Parent { function foo() { echo 'bar'; } } class Child { function foo() { $foo = $this->parentFooCall(); return $foo; } function parentFooCall() { return parent::foo(); } } class ChildTest extend PHPUnit_TestCase { function testFoo() { $mock = $this->getMock('Child', array('foo', 'parentFooCall')); //how do i mock parent methods and simulate responses? } } 

Вот как я это сделал, я понятия не имею, правильно ли это, но это работает:

 class parentClass { public function whatever() { $this->doSomething(); } } class childClass extends parentClass { public $variable; public function subjectUnderTest() { $this->variable = 'whocares'; parent::whatever(); } } 

теперь в тесте я делаю:

 public function testSubjectUnderTest() { $ChildClass = $this->getMock('childClass', array('doSomething')) $ChildClass->expects($this->once()) ->method('doSomething'); $ChildClass->subjectUnderTest(); $this->assertEquals('whocares', $ChildClass->variable); } 

что за ?

Мое рассуждение здесь состоит в том, что все, что я действительно хочу проверить, это то, была ли установлена ​​моя переменная. я действительно не забочусь о том, что происходит в родительском методе, но так как вы не можете запретить вызов родительского метода, что я делаю, это mock зависимые методы родительского метода.

теперь иди и скажи мне, что я неправ 🙂

Я полностью согласен с @Gordon. У меня такая же проблема, но я пробовал несколько сложных концепций.

Мой сценарий похож

 class Parent { // Actual-Parent Class function save() { // do something return $this } } class Child extends Parent { // Subject under test function save() { // do something return parent::save(); } } 

Я создал еще один родительский класс с тем же именем «Родитель» и рассматриваю как заглушку и включаю мой класс-заглушку (родительский) и игнорирую фактического родителя (должен быть включен активный родительский класс в автоматическую загрузку, а родитель-заглушка должен быть включен)

 class Parent { //Stub-Parent class function save() { return $this } } 

Теперь я создаю макет объекта класса Child (через Mock-builder) и завершу свои тестовые примеры с завершением assertSame. 🙂

 $this->assertSame($mock, $mock->save()); 

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

 class Parent { function bar() { echo 'bar'; } } class Child extends Parent { function foo() { parent::bar(); echo 'foo'; } } class mockChild extends Child { function bar() { echo 'baz'; } } class ChildTest extends PHPUnit_TestCase { function testFoo() { $sut = new mockChild(); $sut->foo(); } }