New to testing - testing an abstract class

Discussion of testing theory and practice, including methodologies (such as TDD, BDD, DDD, Agile, XP) and software - anything to do with testing goes here. (Formerly "The Testing Side of Development")

Moderator: General Moderators

Post Reply
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

New to testing - testing an abstract class

Post by Luke »

How would I test an abstract class with simpletest? I'm having a hard time with this :(
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

You test a derived class, maybe a Mock version of it. Abstract classes cannot be instantiated on their own, so there's no direct testing.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

What exactly do you want to test? Perhaps you could post an example and we can work through it together since I'm also picking this stuff up. Using it right now to develop a lexical analyzer 8O
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post by Luke »

d11... see this thread:
viewtopic.php?t=54059

I am trying to test that set of classes.... the registry is abstract and needs to be tested.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

OK, so we've established we can't instantiate the abstract class, we have to extend it. Now, you're extending it with the session class but we don't want that clutter in our tests right? That suggests we need to create stub to use in test. In this case it's simple enough to create a stub since there are no abstract methods to implement (which begs the question, why have you made it an abstract class?)

How about this:

Code: Select all

//Purely so we can instantiate the abstract class
class RegistryStub extends Registry {}

//Just something to add to the registry
class DummyClass {}

class TestOfRegistry extends UnitTestCase
{
    public function testAddedObjectIsReferenced()
    {
        $registry = new RegistryStub();
        $dummy = new DummyClass();
        $registry->register('dummy', $dummy);
        $this->assertReference($dummy, $registry->get('dummy'));
    }
    
    public function testResponseIfNotRegistered()
    {
        $registry = new RegistryStub();
        $registry->register('dummy', new DummyClass());
        $this->assertNotNull($registry->get('dummy'));
        $registry->unregister('dummy');
        $this->assertNull($registry->get('dummy'));
    }
}
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post by Luke »

d11wtq wrote:why have you made it an abstract class?
Well it started off having abstract methods... and I didn't even realize I had weeded all of them out, but I guess it's still abstract because it's always extended (in all of my uses for it so far).
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

I would make it concrete. In case someone wants to use a registry but doesn't want to go through the bother of inheritance, they could do that.

In cases when you do have abstract methods, I would go with extending into a concrete class.

There's another solution (not applicable in your case, but good to keep in mind): factor away from inheritance into composition, so that the parts that need to be tested aren't in the abstract class anymore.

For instance, if I have an abstract DB class that has a concrete implementation for query binding and I want to test that, I can extend to a concrete DB class and then test, or I can factor out the query binding to a DBQueryBinder which is concrete.
Post Reply