Browse Source

unmockify the testsuite for Routing & View

Kevin Pfeifer 1 year ago
parent
commit
4adde21094

+ 48 - 22
tests/TestCase/Routing/Middleware/RoutingMiddlewareTest.php

@@ -17,7 +17,6 @@ declare(strict_types=1);
 namespace Cake\Test\TestCase\Routing\Middleware;
 
 use Cake\Core\Configure;
-use Cake\Core\HttpApplicationInterface;
 use Cake\Http\ServerRequestFactory;
 use Cake\Routing\Exception\MissingRouteException;
 use Cake\Routing\Middleware\RoutingMiddleware;
@@ -26,8 +25,11 @@ use Cake\Routing\RouteBuilder;
 use Cake\Routing\Router;
 use Cake\Routing\RoutingApplicationInterface;
 use Cake\TestSuite\TestCase;
+use Closure;
 use Laminas\Diactoros\Response;
 use PHPUnit\Framework\Attributes\DataProvider;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
 use TestApp\Application;
 use TestApp\Http\TestRequestHandler;
 use TestApp\Middleware\DumbMiddleware;
@@ -194,15 +196,28 @@ class RoutingMiddlewareTest extends TestCase
         Router::reload();
 
         $request = ServerRequestFactory::fromGlobals(['REQUEST_URI' => '/app/articles']);
-        $app = $this->getMockBuilder(Application::class)
-            ->onlyMethods(['pluginRoutes'])
-            ->setConstructorArgs([CONFIG])
-            ->getMock();
-        $app->expects($this->once())
-            ->method('pluginRoutes')
-            ->with($this->isInstanceOf(RouteBuilder::class));
+        $app = new class (CONFIG) extends Application {
+            public function pluginRoutes(RouteBuilder $routes): RouteBuilder
+            {
+                $routes->connect('/app/articles', ['controller' => 'Articles', 'action' => 'index']);
+
+                return $routes;
+            }
+        };
         $middleware = new RoutingMiddleware($app);
-        $middleware->process($request, new TestRequestHandler());
+        $middleware->process($request, new TestRequestHandler(function ($req) {
+            $expected = [
+                'controller' => 'Articles',
+                'action' => 'index',
+                'plugin' => null,
+                'pass' => [],
+                '_ext' => null,
+                '_matchedRoute' => '/app/articles',
+            ];
+            $this->assertEquals($expected, $req->getAttribute('params'));
+
+            return new Response();
+        }));
     }
 
     /**
@@ -446,8 +461,11 @@ class RoutingMiddlewareTest extends TestCase
      */
     public function testAppWithoutContainerApplicationInterface(): void
     {
-        /** @var \Cake\Core\HttpApplicationInterface|\PHPUnit\Framework\MockObject\MockObject $app */
-        $app = $this->createMock(RoutingApplicationInterface::class);
+        $app = new class implements RoutingApplicationInterface {
+            public function routes(RouteBuilder $routes): void
+            {
+            }
+        };
         $this->builder->scope('/', function (RouteBuilder $routes): void {
             $routes->connect('/testpath', ['controller' => 'Articles', 'action' => 'index']);
         });
@@ -483,19 +501,27 @@ class RoutingMiddlewareTest extends TestCase
      *
      * @param callable|null $handleCallback Callback for "handle" method.
      */
-    protected function app($handleCallback = null): HttpApplicationInterface
+    protected function app(?callable $handleCallback = null): Application
     {
-        $mock = $this->createMock(Application::class);
-        $mock->method('routes')
-            ->willReturnCallback(function (RouteBuilder $routes) {
-                return $routes;
-            });
+        $app = new class (CONFIG) extends Application {
+            public ?Closure $handleCallback;
+
+            public function routes(RouteBuilder $routes): void
+            {
+            }
+
+            public function handle(ServerRequestInterface $request): ResponseInterface
+            {
+                if ($this->handleCallback) {
+                    return ($this->handleCallback)($request);
+                }
+
+                return parent::handle($request); // TODO: Change the autogenerated stub
+            }
+        };
 
-        if ($handleCallback) {
-            $mock->method('handle')
-                ->willReturnCallback($handleCallback);
-        }
+        $app->handleCallback = $handleCallback;
 
-        return $mock;
+        return $app;
     }
 }

+ 6 - 10
tests/TestCase/Routing/Route/RouteTest.php

@@ -1038,16 +1038,12 @@ class RouteTest extends TestCase
      */
     public function testParseRequestDelegates(): void
     {
-        /** @var \Cake\Routing\Route\Route|\PHPUnit\Framework\MockObject\MockObject $route */
-        $route = $this->getMockBuilder(Route::class)
-            ->onlyMethods(['parse'])
-            ->setConstructorArgs(['/forward', ['controller' => 'Articles', 'action' => 'index']])
-            ->getMock();
-
-        $route->expects($this->once())
-            ->method('parse')
-            ->with('/forward', 'GET')
-            ->willReturn(['works!']);
+        $route = new class ('/forward', ['controller' => 'Articles', 'action' => 'index']) extends Route {
+            public function parse(string $url, string $method): ?array
+            {
+                return ['works!'];
+            }
+        };
 
         $request = new ServerRequest([
             'environment' => [

+ 7 - 10
tests/TestCase/Routing/RouterTest.php

@@ -2989,20 +2989,17 @@ class RouterTest extends TestCase
      */
     public function testUrlFullUrlReturnFromRoute(): void
     {
-        $url = 'http://example.com/posts/view/1';
-
-        $route = $this->getMockBuilder(Route::class)
-            ->onlyMethods(['match'])
-            ->setConstructorArgs(['/{controller}/{action}/*'])
-            ->getMock();
-        $route->expects($this->any())
-            ->method('match')
-            ->willReturn($url);
+        $route = new class ('/{controller}/{action}/*') extends Route {
+            public function match(array $url, array $context = []): ?string
+            {
+                return 'http://example.com/posts/view/1';
+            }
+        };
 
         Router::createRouteBuilder('/')->connect($route);
 
         $result = Router::url(['controller' => 'Posts', 'action' => 'view', 1]);
-        $this->assertSame($url, $result);
+        $this->assertSame('http://example.com/posts/view/1', $result);
     }
 
     /**

+ 95 - 38
tests/TestCase/TestSuite/Fixture/FixtureHelperTest.php

@@ -17,6 +17,8 @@ declare(strict_types=1);
 namespace Cake\Test\TestCase\TestSuite;
 
 use Cake\Core\Exception\CakeException;
+use Cake\Database\Connection;
+use Cake\Datasource\ConnectionInterface;
 use Cake\Datasource\ConnectionManager;
 use Cake\Test\Fixture\ArticlesFixture;
 use Cake\TestSuite\Fixture\FixtureHelper;
@@ -106,15 +108,26 @@ class FixtureHelperTest extends TestCase
      */
     public function testPerConnection(): void
     {
-        $fixture1 = $this->createMock(TestFixture::class);
-        $fixture1->expects($this->once())
-            ->method('connection')
-            ->willReturn('test1');
+        $fixture1 = new class extends TestFixture {
+            public function connection(): string
+            {
+                return 'test1';
+            }
 
-        $fixture2 = $this->createMock(TestFixture::class);
-        $fixture2->expects($this->once())
-            ->method('connection')
-            ->willReturn('test2');
+            protected function _schemaFromReflection(): void
+            {
+            }
+        };
+        $fixture2 = new class extends TestFixture {
+            public function connection(): string
+            {
+                return 'test2';
+            }
+
+            protected function _schemaFromReflection(): void
+            {
+            }
+        };
 
         ConnectionManager::alias('test', 'test1');
         ConnectionManager::alias('test', 'test2');
@@ -152,23 +165,45 @@ class FixtureHelperTest extends TestCase
      */
     public function testInsertFixturesException(): void
     {
-        $fixture = $this->getMockBuilder(TestFixture::class)->getMock();
-        $fixture->expects($this->once())
-            ->method('connection')
-            ->willReturn('test');
-        $fixture->expects($this->once())
-            ->method('insert')
-            ->will($this->throwException(new PDOException('Missing key')));
-
-        $helper = $this->getMockBuilder(FixtureHelper::class)
-            ->onlyMethods(['sortByConstraint'])
-            ->getMock();
-        $helper->expects($this->any())
-            ->method('sortByConstraint')
-            ->willReturn([$fixture]);
+        $fixture = new class extends TestFixture {
+            public function connection(): string
+            {
+                return 'test';
+            }
+
+            protected function _schemaFromReflection(): void
+            {
+            }
+
+            public function insert(ConnectionInterface $connection): bool
+            {
+                throw new PDOException('Missing key');
+            }
+        };
+
+        $helper = new class extends FixtureHelper {
+            public function sortByConstraint(Connection $connection, array $fixtures): array
+            {
+                return [new class extends TestFixture {
+                    public function connection(): string
+                    {
+                        return 'test';
+                    }
+
+                    protected function _schemaFromReflection(): void
+                    {
+                    }
+
+                    public function insert(ConnectionInterface $connection): bool
+                    {
+                        throw new PDOException('Missing key');
+                    }
+                }];
+            }
+        };
 
         $this->expectException(CakeException::class);
-        $this->expectExceptionMessage('Unable to insert rows for table ``');
+        $this->expectExceptionMessage('Unable to insert rows for table `');
         $helper->insert([$fixture]);
     }
 
@@ -197,23 +232,45 @@ class FixtureHelperTest extends TestCase
      */
     public function testTruncateFixturesException(): void
     {
-        $fixture = $this->getMockBuilder(TestFixture::class)->getMock();
-        $fixture->expects($this->once())
-            ->method('connection')
-            ->willReturn('test');
-        $fixture->expects($this->once())
-            ->method('truncate')
-            ->will($this->throwException(new PDOException('Missing key')));
-
-        $helper = $this->getMockBuilder(FixtureHelper::class)
-            ->onlyMethods(['sortByConstraint'])
-            ->getMock();
-        $helper->expects($this->any())
-            ->method('sortByConstraint')
-            ->willReturn([$fixture]);
+        $fixture = new class extends TestFixture {
+            public function connection(): string
+            {
+                return 'test';
+            }
+
+            protected function _schemaFromReflection(): void
+            {
+            }
+
+            public function truncate(ConnectionInterface $connection): bool
+            {
+                throw new PDOException('Missing key');
+            }
+        };
+
+        $helper = new class extends FixtureHelper {
+            public function sortByConstraint(Connection $connection, array $fixtures): array
+            {
+                return [new class extends TestFixture {
+                    public function connection(): string
+                    {
+                        return 'test';
+                    }
+
+                    protected function _schemaFromReflection(): void
+                    {
+                    }
+
+                    public function truncate(ConnectionInterface $connection): bool
+                    {
+                        throw new PDOException('Missing key');
+                    }
+                }];
+            }
+        };
 
         $this->expectException(CakeException::class);
-        $this->expectExceptionMessage('Unable to truncate table ``');
+        $this->expectExceptionMessage('Unable to truncate table `');
         $helper->truncate([$fixture]);
     }
 }

+ 33 - 33
tests/TestCase/View/Helper/FormHelperTest.php

@@ -217,16 +217,20 @@ class FormHelperTest extends TestCase
      */
     public function testAddWidgetAndRenderWidget(): void
     {
-        $data = [
-            'val' => 1,
-        ];
-        $mock = $this->getMockBuilder(WidgetInterface::class)->getMock();
-        $this->Form->addWidget('test', $mock);
-        $mock->expects($this->once())
-            ->method('render')
-            ->with($data)
-            ->willReturn('HTML');
-        $result = $this->Form->widget('test', $data);
+        $widget = new class implements WidgetInterface
+        {
+            public function render(array $data, ContextInterface $context): string
+            {
+                return 'HTML';
+            }
+
+            public function secureFields(array $data): array
+            {
+                return ['val'];
+            }
+        };
+        $this->Form->addWidget('test', $widget);
+        $result = $this->Form->widget('test', ['val' => 1]);
         $this->assertSame('HTML', $result);
     }
 
@@ -240,25 +244,21 @@ class FormHelperTest extends TestCase
             'unlockedFields' => [],
         ]));
 
-        $data = [
-            'val' => 1,
-            'name' => 'test',
-        ];
-        $mock = $this->getMockBuilder(WidgetInterface::class)->getMock();
-        $this->Form->addWidget('test', $mock);
-
-        $mock->expects($this->once())
-            ->method('render')
-            ->with($data)
-            ->willReturn('HTML');
-
-        $mock->expects($this->once())
-            ->method('secureFields')
-            ->with($data)
-            ->willReturn(['test']);
+        $widget = new class implements WidgetInterface
+        {
+            public function render(array $data, ContextInterface $context): string
+            {
+                return 'HTML';
+            }
 
+            public function secureFields(array $data): array
+            {
+                return ['test'];
+            }
+        };
+        $this->Form->addWidget('test', $widget);
         $this->Form->create();
-        $result = $this->Form->widget('test', $data + ['secure' => true]);
+        $result = $this->Form->widget('test', ['val' => 1, 'name' => 'test', 'secure' => true]);
         $this->assertSame('HTML', $result);
     }
 
@@ -288,7 +288,7 @@ class FormHelperTest extends TestCase
     public function testAddContextProvider(): void
     {
         $context = 'My data';
-        $stub = $this->getMockBuilder(ContextInterface::class)->getMock();
+        $stub = new StubContext();
         $this->Form->addContextProvider('test', function ($request, $data) use ($context, $stub) {
             $this->assertInstanceOf(ServerRequest::class, $request);
             $this->assertSame($context, $data['entity']);
@@ -306,7 +306,7 @@ class FormHelperTest extends TestCase
     public function testAddContextProviderReplace(): void
     {
         $entity = new Article();
-        $stub = $this->getMockBuilder(ContextInterface::class)->getMock();
+        $stub = new StubContext();
         $this->Form->addContextProvider('orm', function ($request, $data) use ($stub) {
             return $stub;
         });
@@ -321,7 +321,7 @@ class FormHelperTest extends TestCase
     public function testAddContextProviderAdd(): void
     {
         $entity = new Article();
-        $stub = $this->getMockBuilder(ContextInterface::class)->getMock();
+        $stub = new StubContext();
         $this->Form->addContextProvider('newshiny', function ($request, $data) use ($stub) {
             if ($data['entity'] instanceof Entity) {
                 return $stub;
@@ -8239,9 +8239,9 @@ class FormHelperTest extends TestCase
         $result = $this->Form->context();
         $this->assertInstanceOf(ContextInterface::class, $result);
 
-        $mock = $this->getMockBuilder(ContextInterface::class)->getMock();
-        $this->assertSame($mock, $this->Form->context($mock));
-        $this->assertSame($mock, $this->Form->context());
+        $stub = new StubContext();
+        $this->assertSame($stub, $this->Form->context($stub));
+        $this->assertSame($stub, $this->Form->context());
     }
 
     /**

+ 13 - 7
tests/TestCase/View/HelperTest.php

@@ -19,11 +19,14 @@ declare(strict_types=1);
 namespace Cake\Test\TestCase\View;
 
 use Cake\Core\Configure;
+use Cake\Event\EventListenerInterface;
 use Cake\Event\EventManager;
 use Cake\Routing\Router;
 use Cake\TestSuite\TestCase;
+use Cake\View\Helper;
 use Cake\View\Helper\HtmlHelper;
 use Cake\View\View;
+use Exception;
 use TestApp\View\Helper\TestHelper;
 use TestPlugin\View\Helper\OtherHelperHelper;
 
@@ -94,14 +97,17 @@ class HelperTest extends TestCase
      */
     public function testThatHelperHelpersAreNotAttached(): void
     {
-        $events = $this->getMockBuilder(EventManager::class)->getMock();
-        $this->View->setEventManager($events);
+        $eventsManager = new class extends EventManager
+        {
+            public function on(string|EventListenerInterface $eventKey, callable|array $options = [], ?callable $callable = null)
+            {
+                throw new Exception('Should not be called');
+            }
+        };
+        $this->View->setEventManager($eventsManager);
 
-        $events->expects($this->never())
-            ->method('on');
-
-        $Helper = new TestHelper($this->View);
-        $Helper->OtherHelper;
+        $helper = new TestHelper($this->View);
+        $this->assertInstanceOf(Helper::class, $helper->OtherHelper);
     }
 
     /**