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());