Which technique should be used for testing abstract class functionality in PHPUnit?
I know three approaches:
- Create fake subclass (looks ugly)
- Test one of real subclasses
- Use getMockForAbs开发者_运维百科tractClass() (contradicts with mocks' mission; also can't stub not-abstract methods)
What the best way according unit test concept?
I would only write tests for concrete classes derived from the abstract class. If you find you are duplicating tests among them, write a superclass and move the duplicated tests there or use getMockForAbstract
class for these.
So if you had something like this:
abstract class Employee
{
protected $name;
public function getName()
{
return $this->name;
}
abstract function doWork();
…
}
class Mechanic extends Employee
{
public function doWork()
{
return // specific to Mechanic
}
}
class Engineer extends Employee
{
public function doWork()
{
return // specific to Engineer
}
}
I'd have a test class for Mechanic and Engineer testing their doWork
implementation, but not their getName
functionality, because that is inherited by the abstract class. For that, I'd write a custom class then or use getMockForAbstractClass
, as shown in the example in the PHPUnit Manual:
- http://www.phpunit.de/manual/3.6/en/test-doubles.html#test-doubles.mock-objects
It depends on how functional the abstract class is. When the abstract class is merely there to provide some basic boilerplate with a bunch of template methods, I limit my testing to the concrete subclasses.
When the abstract class is mostly complete I will either create a concrete subclass for the test in the same file as the test case or I will use a mock. Note that getMockForAbstractClass()
is just a helper that finds all the abstract methods for you. There's nothing stopping you from declaring all the abstract methods plus some concrete ones with getMock()
. For this very reason I override getMock()
in our base test case to merge in all the abstract methods before calling the parent.
精彩评论