diff --git a/.psalm/baseline.xml b/.psalm/baseline.xml
index 2a1443dd805..9f63d36fb39 100644
--- a/.psalm/baseline.xml
+++ b/.psalm/baseline.xml
@@ -201,7 +201,7 @@
null
-
+
$this->type
diff --git a/src/Framework/MockObject/MockBuilder.php b/src/Framework/MockObject/MockBuilder.php
index 09015053b12..c3c84fb645e 100644
--- a/src/Framework/MockObject/MockBuilder.php
+++ b/src/Framework/MockObject/MockBuilder.php
@@ -170,6 +170,8 @@ public function getMockForTrait(): MockObject
/**
* Specifies the subset of methods to mock. Default is to mock none of them.
+ *
+ * @deprecated https://github.com/sebastianbergmann/phpunit/pull/3687
*/
public function setMethods(array $methods = null): self
{
@@ -185,7 +187,7 @@ public function setMethods(array $methods = null): self
*
* @throws RuntimeException
*/
- public function setRealMethods(array $methods): self
+ public function onlyMethods(array $methods): self
{
$reflection = new \ReflectionClass($this->type);
@@ -193,7 +195,35 @@ public function setRealMethods(array $methods): self
if (!$reflection->hasMethod($method)) {
throw new RuntimeException(
\sprintf(
- 'Trying to set mock method "%s", but it does not exist in class "%s"',
+ 'Trying to set mock method "%s" with onlyMethods, but it does not exist in class "%s". Use addMethods() for methods that don\'t exist in the class.',
+ $method,
+ $this->type
+ )
+ );
+ }
+ }
+
+ $this->methods = $methods;
+
+ return $this;
+ }
+
+ /**
+ * Specifies methods that don't exist in the class which you want to mock
+ *
+ * @param string[] $methods
+ *
+ * @throws RuntimeException
+ */
+ public function addMethods(array $methods): self
+ {
+ $reflection = new \ReflectionClass($this->type);
+
+ foreach ($methods as $method) {
+ if ($reflection->hasMethod($method)) {
+ throw new RuntimeException(
+ \sprintf(
+ 'Trying to set mock method "%s" with addMethod, but it exists in class "%s". Use onlyMethods() for methods that exist in the class.',
$method,
$this->type
)
diff --git a/tests/unit/Framework/MockObject/MockBuilderTest.php b/tests/unit/Framework/MockObject/MockBuilderTest.php
index c5d683f41d5..e03f6e8986d 100644
--- a/tests/unit/Framework/MockObject/MockBuilderTest.php
+++ b/tests/unit/Framework/MockObject/MockBuilderTest.php
@@ -60,30 +60,49 @@ public function testSetMethodsAllowsNonExistentMethodNames(): void
$this->assertNull($mock->mockableMethodWithCrazyName());
}
- public function testSetRealMethodsWithNonExistentMethodNames(): void
+ public function testOnlyMethodsWithNonExistentMethodNames(): void
{
$this->expectException(RuntimeException::class);
$this->getMockBuilder(Mockable::class)
- ->setRealMethods(['mockableMethodWithCrazyName'])
+ ->onlyMethods(['mockableMethodWithCrazyName'])
->getMock();
}
- public function testSetRealMethodsWithExistingMethodNames(): void
+ public function testOnlyMethodsWithExistingMethodNames(): void
{
$mock = $this->getMockBuilder(Mockable::class)
- ->setRealMethods(['mockableMethod'])
- ->getMock();
+ ->onlyMethods(['mockableMethod'])
+ ->getMock();
$this->assertNull($mock->mockableMethod());
$this->assertTrue($mock->anotherMockableMethod());
}
+ public function testAddMethodsWithNonExistentMethodNames(): void
+ {
+ $this->expectException(RuntimeException::class);
+
+ $this->getMockBuilder(Mockable::class)
+ ->addMethods(['mockableMethod'])
+ ->getMock();
+ }
+
+ public function testAddMethodsWithExistingMethodNames(): void
+ {
+ $mock = $this->getMockBuilder(Mockable::class)
+ ->addMethods(['mockableMethodWithFakeMethod'])
+ ->getMock();
+
+ $this->assertNull($mock->mockableMethodWithFakeMethod());
+ $this->assertTrue($mock->anotherMockableMethod());
+ }
+
public function testEmptyMethodExceptionsToMockCanBeSpecified(): void
{
$mock = $this->getMockBuilder(Mockable::class)
- ->setMethodsExcept()
- ->getMock();
+ ->setMethodsExcept()
+ ->getMock();
$this->assertNull($mock->mockableMethod());
$this->assertNull($mock->anotherMockableMethod());