Skip to content

Instantly share code, notes, and snippets.

@mvriel
Created October 30, 2012 17:14
Show Gist options
  • Save mvriel/3981617 to your computer and use it in GitHub Desktop.
Save mvriel/3981617 to your computer and use it in GitHub Desktop.
Class IpRange
{
public function setStartingAddress($startingAddress)
{
InputValidator::assertValidAddress($startingAddress);
$this->startingAddress = (int) $startingAddress;
return $this;
}
}
@mvriel
Copy link
Author

mvriel commented Oct 30, 2012

Hmm.. I generally test my abstract classes individually and then in child classes I stub the child class and only stub the expected abstract calls.

Example:

class Super
{
    protected function assertTrue()
    {
        ...
    }
}

class Child extends Super
{
    public function valid()
    {
        return $this->assertTrue();
    }
}

I would test the above using the following test:

class ChildTestCase
{
    function testValid()
    {
        $fixture = $this->getMock('Child', array('assertTrue'));
        $fixture->expects($this->once())->method('assertTrue')->will($this->returnValue(true));

        $this->assertTrue($fixture->valid());
    }

    function testValidWithInvalidInput()
    {
        $fixture = $this->getMock('Child', array('assertTrue'));
        $fixture->expects($this->once())->method('assertTrue')->will($this->returnValue(false));

        $this->assertFalse($fixture->valid());
    }
}

This test case only tests the actual behaviour of valid; I consider the behaviour of the assertTrue() to be unimportant to my unit test since that is governed by my abstract class (which is tested in a single location).

@mvriel
Copy link
Author

mvriel commented Oct 30, 2012

I think you are overstating the value of a mock here. YAGNI, right? With PHP 5.4 I would have used a trait...

I don't see how a trait would make any difference; a trait adds the same testing issues as a static, global function, singleton or any other piece of global state

@mvriel
Copy link
Author

mvriel commented Oct 30, 2012

Let's say I ditch the "staticness" of the InputValidator class... without dependency injection, how would I be able to check if the method was invoked?

That depends on how you make your validation methods visible; when using extension you can Stub your fixture as shown in the previous example. As a trait? You can't. Traits are effectively global state as well. SOLID has Dependency Inversion as a principle because it allows for things like testability.

@andriesss
Copy link

Extension is not an option in my case, given multiple inheritance is (unfortunately) not a language feature of PHP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment