Create mock for class that has constructor arguments

You want to:

Create a mock, but the mocked class requires arguments to be passed in upon construction.

Solution:

Pass an optional third argument to $this->getMock(), in the form of an array of arguments to __construct().

Note that the code in __construct() is run by default when the class is created, so this solution is only for when the code in __construct() is mostly harmless. Otherwise, see Create mock for class with dangerous constructor to make PHPUnit skip the constructor.

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
49
50
51
52
53
54
55
56
57
<?php
 
require_once "PHPUnit/Framework.php";
 
class FilesMultiplier
{
    /*
     * Read a pair of numbers from a file, mutiply, and return.
     */
    public function multiply($inputFile)
    {
        $line = $inputFile->read();
        $parts = explode(" ", $line);
        $a = (integer) $parts[0];
        $b = (integer) $parts[1];
        $result = ($a * $b);
        return $result;
    }
}
 
class FileObject
{
    public function __construct($filename)
    {
        // ... code omitted
    }
 
    /*
     * This function reads a line from a file.
     */
    public function read()
    {
    // ... code omitted
    }
}
 
class TestFilesMultiplier extends PHPUnit_Framework_TestCase
{
    public function test_multiply()
    {
        $multiplier = new FilesMultiplier();
        $inputFile = $this->getMock('FileObject',
                                    array('read'),
                                    array('/dummy/path/to/file'));
 
        $inputFile->expects($this->once())
                  ->method('read')
                  ->will($this->returnValue("3 4"));
 
        $result = $multiplier->multiply($inputFile);
 
        $this->assertEquals($result, 12,
                            "Multiplying 3 by 4 did not give 12 as expected.");
    }
}
 
?>