@TheKeyboard

Metatesting: Testing Constructors

| Comments

If you have a PHP application that makes heavy use of objects (which is probably 95% of you reading this) then you will have objects with constructor methods in them. It is also very likely that there is some stuff going on in those constructors. So how do you test things like this?

Here is the constructor method that we are trying to test:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php

class Alpha
{
    protected $_foo;
    protected $_bar;
    protected $_baz;

    public function __construct()
    {
        $container = Grumpy_Container::getInstance();
        $alphaConfig = $container->alphaConfig();
        $this->_foo = $alphaConfig->foo;
        $this->_bar = $alphaConfig->bar;
        $this->_baz = $alphaConfig->baz;
    }

    // the rest of our class is here
}

In this example, Grumpy_Container is an object that is available via autoloading and it is used as a dependency injection container (DIC).

Okay, so how do we test that the constructor is doing what it is supposed to? We would want to verify that those protected class attributes have been set to values we are expecting.

In order to do that we will also need to override the values in our DIC so when we run the test we have values in there we are expecting.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php

public testConstructorAssignsExpectedAttributeValues()
{
    $container = Grumpy_Container::getInstance();

    // Create our mock configuration object
    $alphaConfig = new stdClass();
    $alphaConfig->foo = 'testfoo';
    $alphaConfig->bar = 'testbar';
    $alphaConfig->baz = 'testbaz';

    // Place this back in the container to override what we have
    $container->alphaConfig = function() use ($alphaConfig) {
        return $alphaConfig;
    };

    // Create our mock object
    $alphaTest = $this->getMockBuilder('Alpha')
        ->disableOriginalConstructor()
        ->getMock();

    // Manually run the constructor
    $alphaTest->__construct();

    // Check for values we expect
    $this->assertAttributeEquals(
        $alphaConfig->foo,
        '_foo',
        $alphaTest,
        'Should set expected foo config value'
    );

    $this->assertAttributeEquals(
        $alphaConfig->bar,
        '_bar',
        $alphaTest,
        'Should set expected foo config value'
    );

    $this->assertAttributeEquals(
        $alphaConfig->baz,
        '_baz',
        $alphaTest,
        'Should set expected bar config value'
    );

}

The magic method here is assertAttributeEquals(). It lets you check the value inside any protected or private class attributes, which is absolutely a requirement in this example. It is probably better to have some other publicly-available methods that can return us the protected (or in some cases private because you don’t want anyone to manipulate them) attributes.

Hope this helps you understand some ways to test your constructors.

Comments