phpunit icon indicating copy to clipboard operation
phpunit copied to clipboard

Make `TestCase` methods `final` that should have been `final` all along

Open sebastianbergmann opened this issue 2 years ago • 8 comments

  • runTest()
  • iniSet()
  • setLocale()
  • createStub()
  • createStubForIntersectionOfInterfaces()
  • createMock()
  • createMockForIntersectionOfInterfaces()
  • createConfiguredMock()
  • createPartialMock()
  • createTestProxy()
  • getMockForAbstractClass()
  • getMockFromWsdl()
  • getMockForTrait()
  • getObjectForTrait()

sebastianbergmann avatar Feb 24 '23 06:02 sebastianbergmann

I'm begging you not to do this. Laravel very much relies on these methods, especially runTest which handles so much of the internal exception throwing: https://github.com/laravel/framework/blob/cc3ccc3d68d112ff6e88eb36314fa8c75592311f/src/Illuminate/Foundation/Testing/TestCase.php#L168

driesvints avatar Apr 03 '23 07:04 driesvints

I'm begging you not to do this. Laravel very much relies on these methods, especially runTest which handles so much of the internal exception throwing: https://github.com/laravel/framework/blob/cc3ccc3d68d112ff6e88eb36314fa8c75592311f/src/Illuminate/Foundation/Testing/TestCase.php#L168

Allowing to override runTest() is just "too much". But I am sure that what you need can be accomplished in another way, even if that way is not implemented yet.

Can you explain why you currently override runTest()? If that is a use case worth supporting, than I am open to implementing a specific API for it.

sebastianbergmann avatar Apr 03 '23 07:04 sebastianbergmann

Thank you for considering it! For Laravel's HTTP testing we check if there's a latest response:

https://github.com/laravel/framework/blob/cc3ccc3d68d112ff6e88eb36314fa8c75592311f/src/Illuminate/Foundation/Testing/TestCase.php#L175

If that's the case we'll transform the exception to provide more info depending on what type of response it is:

https://github.com/laravel/framework/blob/cc3ccc3d68d112ff6e88eb36314fa8c75592311f/src/Illuminate/Testing/TestResponse.php#L1566-L1593

driesvints avatar Apr 03 '23 07:04 driesvints

Would this help?

WIP: Implement TestCase::transformException() hook method (main branch)

diff --git a/src/Framework/TestCase.php b/src/Framework/TestCase.php
index b875580d5..00898d070 100644
--- a/src/Framework/TestCase.php
+++ b/src/Framework/TestCase.php
@@ -671,7 +671,7 @@ final public function runBare(): void
                     null
                 );
             } else {
-                $e = $_e;
+                $e = $this->transformException($_e);
 
                 $this->status = TestStatus::error($e->getMessage());
 
@@ -1465,6 +1465,11 @@ protected function getObjectForTrait(string $traitName, array $arguments = [], s
         );
     }
 
+    protected function transformException(Throwable $t): Throwable
+    {
+        return $t;
+    }

Test.php

<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;

final class OriginalException extends RuntimeException
{
}

final class ModifiedException extends RuntimeException
{
}

final class Test extends TestCase
{
    public function testOne(): void
    {
        throw new OriginalException('original message');
    }

    protected function transformException(Throwable $t): Throwable
    {
        return new ModifiedException('modified message');
    }
}
PHPUnit 10.1-dev by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.4

E                                                                   1 / 1 (100%)

Time: 00:00.019, Memory: 4.00 MB

There was 1 error:

1) Test::testOne
ModifiedException: modified message

/home/sb/Test.php:21

ERRORS!
Tests: 1, Assertions: 0, Errors: 1.

sebastianbergmann avatar Apr 03 '23 09:04 sebastianbergmann

@sebastianbergmann yes that would be useful. Previously we used onNotSuccessfulTest but it no longer exists in PHPUnit 10 and the reason why we need to override runTest() at the moment.

https://github.com/laravel/framework/blob/d68fefe71e5c670cc3d83d9df8ad3b40ed123dac/src/Illuminate/Foundation/Testing/TestCase.php#L295-L308

crynobone avatar Apr 03 '23 10:04 crynobone

@sebastianbergmann yes that would solve this! Thank you 🙂

driesvints avatar Apr 03 '23 11:04 driesvints

Previously we used onNotSuccessfulTest but it no longer exists in PHPUnit 10 and the reason why we need to override runTest() at the moment.

onNotSuccessfulTest() still exists, but can no longer be (ab)used for this.

sebastianbergmann avatar Apr 03 '23 11:04 sebastianbergmann

Reconsider? If your concern with these not being final is people's application's breaking if they override them, create a GitHub saved reply explaining you override those methods at your own risk and any breakages from doing so are not your problem and close the issue?

taylorotwell avatar Apr 03 '23 13:04 taylorotwell