When I'm unit-testing my php code with PHPUnit, I'm trying to figure out the right way to mock an object without mocking any of its methods.
The problem is that if I don't call getMockBuilder()->setMethods()
, then all methods on the object will be mocked and I can't call the method I want to test; but if I do call setMethods()
, then I need to tell it what method to mock but I don't want to mock any methods at all. But I need to create the mock so I can avoid calling the constructor in my test.
Here's a trivial example of a method I'd want to test:
class Foobar
{
public function __construct()
{
// stuff happens here ...
}
public function myMethod($s)
{
// I want to test this
return (strlen($s) > 3);
}
}
I might test myMethod()
with:
$obj = new Foobar();
$this->assertTrue($obj->myMethod('abcd'));
But this would call Foobar's constructor, which I don't want. So instead I'd try:
$obj = $this->getMockBuilder('Foobar')->disableOriginalConstructor()->getMock();
$this->assertTrue($obj->myMethod('abcd'));
But calling getMockBuilder()
without using setMethods()
will result in all of its methods being mocked and returning null, so my call to myMethod()
will return null without touching the code I intend to test.
My workaround so far has been this:
$obj = $this->getMockBuilder('Foobar')->setMethods(array('none'))
->disableOriginalConstructor()->getMock();
$this->assertTrue($obj->myMethod('abcd'));
This will mock a method named 'none', which doesn't exist, but PHPUnit doesn't care. It will leave myMethod() unmocked so that I can call it, and it will also let me disable the constructor so that I don't call it. Perfect! Except that it seems like cheating to have to specify a method name that doesn't exist - 'none', or 'blargh', or 'xyzzy'.
What would be the right way to go about doing this?
question from:
https://stackoverflow.com/questions/9398284/creating-a-mock-in-phpunit-without-mocking-any-methods 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…