diff --git a/src/Support/ExceptionTrace.php b/src/Support/ExceptionTrace.php index 014b88df..1a32855f 100644 --- a/src/Support/ExceptionTrace.php +++ b/src/Support/ExceptionTrace.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Pest\Support; use Closure; +use PHPUnit\Framework\TestCase; use Throwable; /** @@ -15,8 +16,7 @@ final class ExceptionTrace private const UNDEFINED_METHOD = 'Call to undefined method P\\'; /** - * Ensures the given closure reports - * the good execution context. + * Ensures the given closure reports the good execution context. * * @return mixed * @@ -28,8 +28,14 @@ final class ExceptionTrace return $closure(); } catch (Throwable $throwable) { if (Str::startsWith($message = $throwable->getMessage(), self::UNDEFINED_METHOD)) { + $class = preg_match('/^Call to undefined method ([^:]+)::/', $message, $matches) === false ? null : $matches[1]; + $message = str_replace(self::UNDEFINED_METHOD, 'Call to undefined method ', $message); + if (class_exists($class) && count(class_parents($class)) > 0 && array_values(class_parents($class))[0] === TestCase::class) { + $message .= '. Did you forget to use the [uses()] function? https://pestphp.com/docs/configuring-tests'; + } + Reflection::setPropertyValue($throwable, 'message', $message); } diff --git a/tests/.snapshots/success.txt b/tests/.snapshots/success.txt index 347a236b..1db371c3 100644 --- a/tests/.snapshots/success.txt +++ b/tests/.snapshots/success.txt @@ -903,6 +903,10 @@ ✓ it computes the dataset scope with ('/var/www/project/tests/Featur…rs.php', '/var/www/project/tests/Featur…rs.php') #2 ✓ it computes the dataset scope with ('/var/www/project/tests/Featur…ts.php', '/var/www/project/tests/Featur…ollers') + PASS Tests\Unit\Support\ExceptionTrace + ✓ it ensures the given closures reports the correct class name + ✓ it ensures the given closures reports the correct class name and suggests the [uses()] function + PASS Tests\Unit\Support\Reflection ✓ it gets file name from closure ✓ it gets property values @@ -1004,4 +1008,4 @@ PASS Tests\Visual\Version ✓ visual snapshot of help command output - Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 14 skipped, 703 passed (1702 assertions) \ No newline at end of file + Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 14 skipped, 705 passed (1706 assertions) \ No newline at end of file diff --git a/tests/Unit/Support/ExceptionTrace.php b/tests/Unit/Support/ExceptionTrace.php new file mode 100644 index 00000000..c3f665a0 --- /dev/null +++ b/tests/Unit/Support/ExceptionTrace.php @@ -0,0 +1,21 @@ +throws( + Exception::class, + 'Call to undefined method Tests\IntentionallyNotExisting::testBasic().', +); + +it('ensures the given closures reports the correct class name and suggests the [uses()] function', function () { + $this->get(); +})->throws( + Error::class, + 'Call to undefined method Tests\Unit\Support\ExceptionTrace::get(). Did you forget to use the [uses()] function? https://pestphp.com/docs/configuring-tests', +); diff --git a/tests/Visual/Parallel.php b/tests/Visual/Parallel.php index 4d131f2b..ab8a20e9 100644 --- a/tests/Visual/Parallel.php +++ b/tests/Visual/Parallel.php @@ -15,6 +15,6 @@ $run = function () { }; test('parallel', function () use ($run) { - expect($run())->toContain('Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 11 skipped, 692 passed (1688 assertions)') + expect($run())->toContain('Tests: 2 deprecated, 3 warnings, 4 incomplete, 1 notice, 4 todos, 11 skipped, 694 passed (1692 assertions)') ->toContain('Parallel: 3 processes'); })->skip(PHP_OS_FAMILY === 'Windows');