Skip to content

Fix: trait-only file-level binding no longer discards the directory binding - #10

Merged
MrPunyapal merged 1 commit into
pestphp:5.xfrom
webard:fix/file-level-bindings-discard-directory-bindings
Aug 8, 2026
Merged

Fix: trait-only file-level binding no longer discards the directory binding#10
MrPunyapal merged 1 commit into
pestphp:5.xfrom
webard:fix/file-level-bindings-discard-directory-bindings

Conversation

@webard

@webard webard commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

When a test file declares a binding of its own that names only a trait (uses(SomeTrait::class) or pest()->use(SomeTrait::class)), PestTestCaseType::resolve() drops the test case class bound to that file's directory in Pest.php and falls back to PHPUnit\Framework\TestCase.

Every method that exists only on the real base class — in Laravel that is artisan(), get(), travelTo(), withoutExceptionHandling(), mock() — is then reported as undefined, and every method that also exists on PHPUnit\Framework\TestCase is silently checked against the wrong class.

Reproduction

tests/
  Pest.php
  Feature/
    ExampleTest.php

tests/Pest.php:

pest()->extend(MyTestCase::class)->in('Feature');

tests/Feature/ExampleTest.php:

uses(SomeTrait::class);   // or: pest()->use(SomeTrait::class);

it('resolves the bound test case', function (): void {
    assertType(MyTestCase::class, $this);
});

Expected: MyTestCase
Actual: PHPUnit\Framework\TestCase

Removing the uses(SomeTrait::class) line makes the type correct again.

Cause

src/Type/Pest/PestTestCaseType.php:

$bindings = $this->pestConfigReader->resolveFileBindings($filePath);

if ($bindings === []) {
    $bindings = $this->pestConfigReader->resolveBindings($filePath);
}

File-level bindings replace directory-level bindings. A trait-only binding is non-empty, so the directory bindings are never read; $classNames ends up empty and the fallback assigns PHPUnit\Framework\TestCase.

Impact

The failure is quiet. PHPUnit\Framework\TestCase carries every assert* method and expect() is a global function, so most test files analyse identically under either type and report nothing. The downgrade only surfaces where a file happens to call a method exclusive to the bound base class.

@webard

webard commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Sorry, I didn’t notice this. It is probably a duplicate of #8. I’ll leave it up to the maintainer to decide which solution to choose.

@MrPunyapal

Copy link
Copy Markdown
Collaborator

@webard have you tried latest 👀

@webard

webard commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Yes, I’m on the latest version. Actually, 5.0.1 (latest) introduces this problem, because it adds this file: PestTestCaseType.php

@MrPunyapal
MrPunyapal merged commit 6a84a5e into pestphp:5.x Aug 8, 2026
@MrPunyapal

Copy link
Copy Markdown
Collaborator

Thanks 👍

@webard
webard deleted the fix/file-level-bindings-discard-directory-bindings branch August 8, 2026 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants