模拟对象并保留其他方法的功能

Say for example I have this class:

class Foo {

    public function add($x, $y)
    {
        return $x + $y;
    }

    public function subtract($x, $y)
    {
        return $x - $y;
    }
}

and I wanted to change the behavior of the add method only:

$mock = $this->getMock('Foo');
$mock->expects($this->once())->method('add')->will($this->returnCallback(function ($x, $y) {
    return ($x + 0) + ($y + 0);
}));

$this->assertEquals(4, $mock->add(2,2));
$this->assertEquals(2, $mock->subtract(4,2));

Why is my subtract method now returning null? I was expecting it to behave usual.

Failed asserting that null matches expected 2.

Use like this:

$mock = m::mock('Foo[add]');

You need to do a partial mock specifying to getMock what method you want to mock:

$mock = $this->getMock('Foo', array('add');

In this way only the add method is mocked, the rest of the object is behaving as usual.