From ff787e67a934220b83b675721e2853ea28f88558 Mon Sep 17 00:00:00 2001 From: David Fox Date: Thu, 9 May 2019 15:12:28 -0400 Subject: [PATCH] MockBuilder method to verify mock method existence --- src/Framework/MockObject/MockBuilder.php | 25 +++++++++++++++++ .../Framework/MockObject/MockBuilderTest.php | 28 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/Framework/MockObject/MockBuilder.php b/src/Framework/MockObject/MockBuilder.php index 46a421858e2..093a8ff55c4 100644 --- a/src/Framework/MockObject/MockBuilder.php +++ b/src/Framework/MockObject/MockBuilder.php @@ -178,6 +178,31 @@ public function setMethods(array $methods = null): self return $this; } + /** + * Specifies the subset of methods to mock, requiring each to exist in the class + */ + public function setRealMethods(array $methods = null): self + { + if ($methods) { + $reflection = new \ReflectionClass($this->type); + + foreach ($methods as $method) { + if (!$reflection->hasMethod($method)) { + throw new RuntimeException( + \sprintf( + 'Trying to set mock method "%s" which cannot be configured because it does not exist', + $method + ) + ); + } + } + } + + $this->methods = $methods; + + return $this; + } + /** * Specifies the subset of methods to not mock. Default is to mock all of them. */ diff --git a/tests/unit/Framework/MockObject/MockBuilderTest.php b/tests/unit/Framework/MockObject/MockBuilderTest.php index 3d22478c2ba..c5d683f41d5 100644 --- a/tests/unit/Framework/MockObject/MockBuilderTest.php +++ b/tests/unit/Framework/MockObject/MockBuilderTest.php @@ -51,6 +51,34 @@ public function testMethodExceptionsToMockCanBeSpecified(): void $this->assertNull($mock->anotherMockableMethod()); } + public function testSetMethodsAllowsNonExistentMethodNames(): void + { + $mock = $this->getMockBuilder(Mockable::class) + ->setMethods(['mockableMethodWithCrazyName']) + ->getMock(); + + $this->assertNull($mock->mockableMethodWithCrazyName()); + } + + public function testSetRealMethodsWithNonExistentMethodNames(): void + { + $this->expectException(RuntimeException::class); + + $this->getMockBuilder(Mockable::class) + ->setRealMethods(['mockableMethodWithCrazyName']) + ->getMock(); + } + + public function testSetRealMethodsWithExistingMethodNames(): void + { + $mock = $this->getMockBuilder(Mockable::class) + ->setRealMethods(['mockableMethod']) + ->getMock(); + + $this->assertNull($mock->mockableMethod()); + $this->assertTrue($mock->anotherMockableMethod()); + } + public function testEmptyMethodExceptionsToMockCanBeSpecified(): void { $mock = $this->getMockBuilder(Mockable::class)