2

I've following abstract class and have a question about how to write a unit test for this. Is this in fact needed? As this class doesn't have any concrete methods.

<?php

abstract class PickupPoint_Abstract {
    public function __construct($client) {}
    public function getPickupPoints($countryCode, $postalCode, $city) {}
    public function getPickupPointDetails($pickupPointId, $countryCode) {} }
hakre
  • 193,403
  • 52
  • 435
  • 836
tom
  • 8,189
  • 12
  • 51
  • 70

3 Answers3

4

Since you can't test for any expected behavior it seems really hard to produce any meaningful test.


If you have at least one concrete method you can mock the class and test that one method but without any code to be tested i'd say you are good to go.

( I guess you know that always but for sake of completion: See Example 11.8 for getMockForAbstractClass on the phpunit site )


Even so i'm curios to why you didn't define the methods as abstract like this:

<?php
abstract class PickupPoint_Abstract {
    abstract public function __construct($client);
    abstract public function getPickupPoints($countryCode, $postalCode, $city);
    abstract public function getPickupPointDetails($pickupPointId, $countryCode); }

since only then the interpreter will enforce that all methods are implemented in the child classes.

edorian
  • 38,542
  • 15
  • 125
  • 143
2

No, you don't need to test it, because there is nothing to test.

By the way abstract methods should be defined like

<?php
abstract class PickupPoint_Abstract {
    public function __construct($client) {}
    abstract public function getPickupPoints($countryCode, $postalCode, $city);
    abstract public function getPickupPointDetails($pickupPointId, $countryCode);
}
?>

You made hooks, which may not be overridden.

See Class Abstraction.

Christian Strempfer
  • 7,291
  • 6
  • 50
  • 75
  • I did forgot the abstract! Thx. – tom Sep 15 '10 at 09:03
  • 1
    I politely disagree, I think the op's way of declaring his methods can be overriden in child classes they just don't need to be defined, thus they are not abstract. In such context the abstract acts as a regular class with all functions defined, missing out on true OOP abstraction. – Stephane Gosselin May 18 '11 at 12:17
  • I don't understand your comment. You don't agree about what? – Christian Strempfer May 18 '11 at 13:04
1

For this case and for testing an Interface I would write at least 3 tests:

protected setUp() {
    $this->_object = $this->getMockForAbstractClass(
       'PickupPoint_Abstract', array(), '', false
    );
}

public function testInstanceOf() {
    $this->assertInstanceOf('PickupPoint_Abstract', $this->_object);
}

public function testMethodsExistance() {
    $methods = get_class_methods($this->_object);
    $this->assertTrue(in_array('getPickupPoints', $methods));
    $this->assertTrue(in_array('getPickupPointDetails', $methods));
    $this->assertTrue(in_array('__construct', $methods));
}

public function testMethodCount() {
    $methods = get_class_methods($this->_object);
    /**
     * PHPUnit add seven own methods in 3.6.11 + __clone + count of these methods
     */
    $this->assertEquals(11, count($methods));
}

With these tests you will prevent typos, check the existance of the required methods and if any new methods will be added, this test will be broken, because the number of methods has changed, and this is the behavior we want.

Well this works fine for me. I always use this tests for interfaces, but i think it can be used for abstract classes to!