Unit testing of abstract classes doesn't necessary mean testing the interface, as abstract classes can have concrete methods, and this concrete methods can be tested.
It is not so uncommon, when writing some library code, to have certain base class that you expect to extend in your application layer. And if you want to make sure that library code is tested, you need means to UT the concrete methods of abstract classes.
Personally, I use PHPUnit, and it has so called stubs and mock objects to help you testing this kind of things.
Straight from PHPUnit manual:
abstract class AbstractClass
{
public function concreteMethod()
{
return $this->abstractMethod();
}
public abstract function abstractMethod();
}
class AbstractClassTest extends PHPUnit_Framework_TestCase
{
public function testConcreteMethod()
{
$stub = $this->getMockForAbstractClass('AbstractClass');
$stub->expects($this->any())
->method('abstractMethod')
->will($this->returnValue(TRUE));
$this->assertTrue($stub->concreteMethod());
}
}
Mock object give you several things:
- you are not required to have concrete implementation of abstract class, and can get away with stub instead
- you may call concrete methods and assert that they perform correctly
- if concrete method relies to unimplemented (abstract) method, you may stub the return value with will() PHPUnit method
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…