Reputation: 16563
Is it possible to have PHPUnit fail when any unconfigured method is called on a mock object?
Example;
$foo = $this->createMock(Foo::class);
$foo->expects($this->any())->method('hello')->with('world');
$foo->hello('world');
$foo->bye();
This test will succeed. I would like it to fail with
Foo::bye() was not expected to be called.
P.S. The following would work, but this means I'd have to list all configured methods in the callback. That's not a suitable solution.
$foo->expects($this->never())
->method($this->callback(fn($method) => $method !== 'hello'));
Upvotes: 4
Views: 354
Reputation: 1653
What you're looking for is to disable the automatic generation of return values when no return value is configured. Once you disable this, if a method is called that you didn't explicitly define, you'll get the following test failure:
Return value inference disabled and no expectation set up for Foo\Bar::myMethod()
Starting with PHPUnit 11.1.0, you can add the following attribute to your test class:
use PHPUnit\Framework\Attributes\DisableReturnValueGenerationForTestDoubles;
#[DisableReturnValueGenerationForTestDoubles]
class MyTest extends TestCase
Prior to PHPUnit 10, you could override this method in your test class:
public function getMockBuilder(string $className): MockBuilder
{
return parent::getMockBuilder($className)->disableAutoReturnValueGeneration();
}
To do the same in PHPUnit 10 or 11.0, I suppose you'd have to create some custom mock method (eg. createStrictMock()
), as most of the base methods were made final
in 10.0 and can no longer be overridden.
Upvotes: 1
Reputation: 16563
This is done by disabling auto-return value generation.
$foo = $this->getMockBuilder(Foo::class)
->disableAutoReturnValueGeneration()
->getMock();
$foo->expects($this->any())->method('hello')->with('world');
$foo->hello('world');
$foo->bye();
This will result in
Return value inference disabled and no expectation set up for Foo::bye()
Note that it's not required for other methods (like hello
) to define a return method.
Upvotes: 6