Type hinting and unit testing

Ok, I’m not an expert with PHP so I have a question about type hinting. I was trying to unit test some models (as in MVC) from a standard phpunit class. The problem was that the constructor of that class expected a certain type of object as parameter to the constructor. Normally I would mock the object and that works with any language that allows duck typing. I used to think PHP was the same but apparently not. In fact I feel the same frustrations as when working with a statically typed language.

Does anyone have any ideas on how to mock test classes whose constructors have type hinted arguments?

Do you need that constructor into your tests?
If no, you may extend the class and rewrite the constructor

<?php

class some {
    public function __construct( Obj $ob ) { }
}

// into your test
class someForTest extends some {
    public function __construct( { }
}

// now, test someForTest


If yes, if mocking the Obj class doesn’t work, I am out of ideas.
It should work!

Yup, I agree. PHP’s type hinting is inheritance friendly. So, for example, if you have code like this:

class SessionStorage
{}

class User
{
    public function __construct(SessionStorage $storage)
    {}
}

$storage = new SessionStorage('SESSION_ID');
$user = new User($storage);

Then this mocking code should work:

class MockSessionStorage extends SessionStorage
{}

$storage = new MockSessionStorage('SESSION_ID');
$user = new User($storage);

Or the other option is to use interfaces, which I suppose you could think of as language-enforced duck typing.

interface DuckInterface
{
    public function quack();
}

class RealDuck implements DuckInterface
{
    public function quack()
    {}
}

class MockDuck implements DuckInterface
{
    public function quack()
    {}
}

class User
{
    public function __construct(DuckInterface $duck)
    {}
}

The problem you are facing is due to the intersection of practices built on differing philosophical design assumptions so let me begin by setting some background of what those philosophies are.

[indent]The Duck Typing Philosophy
Don’t declare any interfaces, use any type hints, or check the types of anything. Anything goes! Occasionally you may wish to test if method_exists() to tell the difference between things.

[indent]:slight_smile: No boilerplate
:slight_smile: Very flexible
:frowning: No machine verification whether you are doing anything correct; you’re on your own Jim[/indent]

The Concrete Typing Philosophy
Use type hints to make sure you are getting the exact right things, no interfaces required.

[indent]:slight_smile: No boilerplate
:slight_smile: Machine verifies you’re doing the right thing all the time
:frowning: Very inflexible[/indent]

Type to Interfaces Philosophy
Type hint a lot but only ever to interfaces. Make pretty much all your classes implement interfaces.

[indent]:slight_smile: Very flexible
:slight_smile: Lots of machine verification
:frowning: Lots of boilerplate (interface declarations)[/indent]

Hybrid Philosophy
Combination of the above based on perceived needs at the time.

[indent]:slight_smile: Only some of the boilerplate of Type to Interfaces
:frowning: But only some of the protection
:slight_smile: Get flexibility where you need it
:frowning: Have to spend time thinking about which philosophy is appropriate
:frowning: How do you know if you are going to need protection? I mean, you should always be writing correct code, right?
:frowning: How do you know where you are going to need flexibility? Sure, you can guess but who really knows[/indent][/indent]

OK, back to the main event. The problem you are having is the mocking relies on flexibility being a fundamental trait of your design philosophy. I think this is good because flexibility is probably the most important thing. (Hence all this stuff about TDD helping you to create better designs and stuff.) So if you agree with that I hope you will also agree concrete typing (the philosophy used by this particular model you want to test) is the worst philosophy. It’s something you do because you can’t be bothered to declare an interface right now with on the understanding that you aren’t going to leave it like that and you sure as hell aren’t going to subject it to someone else.

Also, did you realize that constructors actually limit flexibility? A constructor is a special thing designed to control the creation of an object so that it can’t be put into an inconsistent state. The cost of this is that you lose the ability to say how you would like the object to be constructed. So this is another instance of the classic safety vs. flexibility problem. The traditional solution, or should I say the solution that came out of C++, is the factory: push the construction behavior up into another object and then we can always create other forms of construction. Smalltalk however had a much lighter weight solution: allow more than one constructor.

You can do this in PHP by not declaring __construct() and instead using static methods to construct your classes:

class Animal {
   static function Dog() { return self::base('Dog', 'woof!'); }
   static function Cow() { return self::base('Cow', 'moooo!'); }
   static function Base($species, $snd) {
      $o = new self;
      $o->species = $species;
      $o->snd = $snd; }
   function describeYourself() {
      return 'I am a ' . $this->species . ' and I go ' . $this->snd; }
   static function SamuelLJackson() {
      return self::base('bad-ass mother****er', '"get your dirty hands off me!"'); } }

(I like to begin them with an uppercase to indicate that they are constructors as opposed to some other static method.) If that was the technique used in your model class you could simply declare an alternate constructor and you’d be fine.

None of this is perfect however. I always felt like OO suffered from this problem of having to choose between lots of boilerplate, nailing everything down real inflexible like, or doing nothing just risking yo ass that everything has been done correctly. Of course the second you try to do anything on any kind of scale the boilerplate becomes the only sane choice. The real solution is to remove the statefulness and dependency on names as a means of connection intrinsic to OO. This is pretty much what pure functional programming (PFP) does but that moves you into a radically different style of programming. For instance you wouldn’t even have mocking in PFP because you don’t have things talking to one another through methods, you only have values being passed in and out of functions. You could think of this as classes each with exactly one method always called doIt() or something.

In the case that you can’t change this model you want to test at all then you could use vectorialpx’s solution. The downside to that is that you may need to copy over behavior that is in the constructor. That sort of bypasses the point of mocking with regards to the constructor but that’s not a big point. The other solution is to use eval. Yep. Generate a subclass of the class that in the type hint and have all the required methods point directly to an internal mock instance. Some mock libraries may even do this for you. I’m not familiar with PHPUnit, I always used SimpleTest.

Yeah, I think the inheritance subclass suggestion could work in my case. I think in this case the class was over burdened by stronger coupling than was necessary. Insufficient separation of concerns. I think these are the issues one deals with when working on team projects.

I got a bit confused when I saw the type hinting having had more experience with python and to a lesser degree, ruby, and their very loose duck typing. Ruby of course opts for the greatest flexibility with adding or subtracting methods from classes at runtime and is its trademark. This means that Ruby apps have to be tested that more thoroughly compared to python or php. However it seems that PHP has a stronger C++ philosophical bias than I realised.

Yeah, compared to Python and Ruby, PHP is more like Java, which was in turn inspired by C++. It’s kind of an unfortunate heritage. You can certain adopt a more duck-typey philosophy in PHP though. I do, although I don’t really use existing frameworks and I tend to do things with functions as much as possible. If you look at a lot of PHP libraries you see one-class-per-file, long docblocks above each method, the visibility (public, protected, or private) always explicitly specified. I hate all that crap.

Off Topic:

Off topic somewhat and not PHP-related, but Ovid (a Perl guy) has given a lot of talks on both testing and inheritence, but couldn’t find one I’m sure he gave on mocking and inheritence…

Roles vs inheritence, touching on the flexibility vs rigidity point mentioned:
https://www.youtube.com/watch?v=cjoWu4eq1Tw (I saw a version of this one at FOSDEM in 2013 but couldn’t find that one)

PHP 5.4+ should have similar

I haven’t taken the time to view the entire video but I assume you’re talking about traits which are a welcomed addition to PHP.

That would be programming to an interface rather than implementation. PHP 5.4+ you could also use traits but I don’t necessarily believe it is good to go trait crazy either.