How do I test an abstract class works in PHPUnit?
I'd expect that I'd have to create some sort of object as part of the test? though - I've no idea the best practice for this, or if phpunit allows for this
How do I test an abstract class works in PHPUnit?
I'd expect that I'd have to create some sort of object as part of the test? though - I've no idea the best practice for this, or if phpunit allows for this
When using unit testing, you do not test the interface per-se but the functionality. You cant test the functionality of an abstract class because it has none.
When you do a test you first write the test before you write the interface. For example: I might write the following test:
$user = UserFactory::CreateUser();
$user->user_username = "nelson";
$user->Save();
$id = $user->user_id;
$user2 = UserFacotry::CreateUser();
$user2->Load($id);
if ($user2->user_username != "nelson")
die a miserable death
Before I actually write the code. After that, I would write the user abstract class:
abstract class IUser
{
abstract function Load();
abstract function Save();
}
Then I would write a User class that extends IUser. Then I would write the UserFactory that returns a User object. Then I would run the test again to see if it works.
:)
Eran, your method should work, but it goes against the tendency of writing the test before the actual code.
What I would suggest is to write your tests on the desired functionality of a non-abstract subclass of the abstract class in question, then write both the abstract class and the implementing subclass, and finally run the test.
Your tests should obviously test the defined methods of the abstract class, but always via the subclass.
Nelson's answer is wrong.
Abstract classes don't require all of their methods to be abstract.
The implemented methods are the ones we need to test.
What you can do is create a fake stub class on the unit test file, have it extend the abstract class and implement only what's required with no functionality at all, of course, and test that.
Cheers.
Agree with skqr, Nelson seems to miss the point of question completely. At least it has little relevance in context of PHP5 abstract classes, I guess.
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: